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.



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

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.



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

def coder
  @coder
end

#streamsObject (readonly)

Returns the value of attribute streams.



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

def streams
  @streams
end

#subscriptionsObject (readonly)

Returns the value of attribute subscriptions.



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

def subscriptions
  @subscriptions
end

Instance Method Details

#closeObject



87
88
89
# File 'lib/lite_cable/connection/base.rb', line 87

def close
  socket.close
end

#cookiesObject

Request cookies



97
98
99
# File 'lib/lite_cable/connection/base.rb', line 97

def cookies
  request.cookies
end

#disconnected?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/lite_cable/connection/base.rb', line 101

def disconnected?
  @_disconnected == true
end

#handle_closeObject



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

def handle_close
  disconnected!
  subscriptions.remove_all

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

#handle_command(websocket_message) ⇒ Object



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

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



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

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



92
93
94
# File 'lib/lite_cable/connection/base.rb', line 92

def request
  socket.request
end

#transmit(cable_message) ⇒ Object



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

def transmit(cable_message)
  return if disconnected?

  socket.transmit encode(cable_message)
end