Class: LiteCable::Connection::Base

Inherits:
Object
  • Object
show all
Includes:
Authorization, Identification, Logging
Defined in:
lib/lite_cable/connection/base.rb

Overview

A Connection object represents a client “connected” to the application. It contains all of the channel subscriptions. Incoming messages are then routed to these channel subscriptions based on an identifier sent by the consumer. The Connection itself does not deal with any specific application logic beyond authentication and authorization.

Here’s a basic example:

module MyApplication
  class Connection < LiteCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    def disconnect
      # Any cleanup work needed when the cable connection is cut.
    end

    private
      def find_verified_user
        User.find_by_identity(cookies[:identity]) ||
          reject_unauthorized_connection
      end
  end
end

First, we declare that this connection can be identified by its current_user. This allows us to later be able to find all connections established for that current_user (and potentially disconnect them). You can declare as many identification indexes as you like. Declaring an identification means that an attr_accessor is automatically set for that key.

Second, we rely on the fact that the connection is established with the cookies from the domain being sent along. This makes it easy to use cookies that were set when logging in via a web interface to authorize the connection.

Constant Summary

Constants included from Logging

Logging::PREFIX

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

logger

Methods included from Authorization

#reject_unauthorized_connection

Methods included from Identification

#fetch_identifier, #identifier, #identifiers, #identifiers_hash, #identifiers_json, prepended

Constructor Details

#initialize(socket, coder: nil) ⇒ Base

Returns a new instance of Base.



47
48
49
50
51
52
53
# File 'lib/lite_cable/connection/base.rb', line 47

def initialize(socket, coder: nil)
  @socket = socket
  @coder = coder || LiteCable.config.coder

  @subscriptions = Subscriptions.new(self)
  @streams = Streams.new(socket)
end

Instance Attribute Details

#coderObject (readonly)

Returns the value of attribute coder.



45
46
47
# File 'lib/lite_cable/connection/base.rb', line 45

def coder
  @coder
end

#streamsObject (readonly)

Returns the value of attribute streams.



45
46
47
# File 'lib/lite_cable/connection/base.rb', line 45

def streams
  @streams
end

#subscriptionsObject (readonly)

Returns the value of attribute subscriptions.



45
46
47
# File 'lib/lite_cable/connection/base.rb', line 45

def subscriptions
  @subscriptions
end

Instance Method Details

#closeObject



85
86
87
# File 'lib/lite_cable/connection/base.rb', line 85

def close
  socket.close
end

#cookiesObject

Request cookies



95
96
97
# File 'lib/lite_cable/connection/base.rb', line 95

def cookies
  request.cookies
end

#disconnected?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/lite_cable/connection/base.rb', line 99

def disconnected?
  @_disconnected == true
end

#handle_closeObject



64
65
66
67
68
69
70
# File 'lib/lite_cable/connection/base.rb', line 64

def handle_close
  disconnected!
  subscriptions.remove_all

  disconnect if respond_to?(:disconnect)
  log(:debug) { log_fmt("Closed") }
end

#handle_command(websocket_message) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/lite_cable/connection/base.rb', line 72

def handle_command(websocket_message)
  command = decode(websocket_message)
  subscriptions.execute_command command
rescue Subscriptions::Error, Channel::Error, Channel::Registry::Error => e
  log(:error, log_fmt("Connection command failed: #{e}"))
  close
end

#handle_openObject



55
56
57
58
59
60
61
62
# File 'lib/lite_cable/connection/base.rb', line 55

def handle_open
  connect if respond_to?(:connect)
  send_welcome_message
  log(:debug) { log_fmt("Opened") }
rescue UnauthorizedError
  log(:debug) { log_fmt("Authorization failed") }
  close
end

#requestObject

Rack::Request instance of underlying socket



90
91
92
# File 'lib/lite_cable/connection/base.rb', line 90

def request
  socket.request
end

#transmit(cable_message) ⇒ Object



80
81
82
83
# File 'lib/lite_cable/connection/base.rb', line 80

def transmit(cable_message)
  return if disconnected?
  socket.transmit encode(cable_message)
end