Class: Ably::Realtime::Connection::WebsocketTransport Private

Inherits:
EventMachine::Connection
  • Object
show all
Extended by:
Modules::Enum
Includes:
Modules::EventEmitter, Modules::StateEmitter
Defined in:
lib/ably/realtime/connection/websocket_transport.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

EventMachine WebSocket transport

Constant Summary collapse

STATE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Valid WebSocket connection states

ruby_enum('STATE',
  :initialized,
  :connecting,
  :connected,
  :disconnecting,
  :disconnected
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Modules::StateEmitter

#once_or_if, #once_state_changed, #state, #state=, #state?, #unsafe_once_or_if, #unsafe_once_state_changed

Methods included from Modules::EventEmitter

#emit, #off, #on, #once, #unsafe_off, #unsafe_on, #unsafe_once

Constructor Details

#initialize(connection, url) ⇒ WebsocketTransport

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of WebsocketTransport.



23
24
25
26
27
28
29
30
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 23

def initialize(connection, url)
  @connection = connection
  @state      = STATE.Initialized
  @url        = url
  @host       = URI.parse(url).hostname

  setup_event_handlers
end

Instance Attribute Details

#__incoming_protocol_msgbus__Ably::Util::PubSub (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Websocket Transport internal incoming protocol message bus.

Returns:



139
140
141
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 139

def __incoming_protocol_msgbus__
  @__incoming_protocol_msgbus__ ||= create_pub_sub_message_bus
end

#__outgoing_protocol_msgbus__Ably::Util::PubSub (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Websocket Transport internal outgoing protocol message bus.

Returns:



146
147
148
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 146

def __outgoing_protocol_msgbus__
  @__outgoing_protocol_msgbus__ ||= create_pub_sub_message_bus
end

#hostObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 21

def host
  @host
end

Instance Method Details

#certificate_storeObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



124
125
126
127
128
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 124

def certificate_store
  @certificate_store ||= OpenSSL::X509::Store.new.tap do |store|
    store.set_default_paths
  end
end

#connection_completedObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Remote TCP connection attempt completes successfully Required EventMachine::Connection interface



55
56
57
58
59
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 55

def connection_completed
  change_state STATE.Connected
  start_tls(tls_opts) if client.use_tls?
  driver.start
end

#disconnectvoid

This method returns an undefined value.

Disconnect the socket transport connection and write all pending text. If Disconnected state is not automatically emitted, it will be emitted automatically



36
37
38
39
40
41
42
43
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 36

def disconnect
  close_connection_after_writing
  change_state STATE.Disconnecting
  create_timer(2) do
    # if connection is not disconnected within 2s, set state as disconnected
    change_state STATE.Disconnected unless disconnected?
  end
end

#post_initObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Network connection has been established Required EventMachine::Connection interface



47
48
49
50
51
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 47

def post_init
  clear_timer
  change_state STATE.Connecting
  setup_driver
end

#ready_for_release?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

True if socket connection is ready to be released i.e. it is not currently connecting or connected

Returns:

  • (Boolean)


132
133
134
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 132

def ready_for_release?
  !connecting? && !connected?
end

#receive_data(data) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called by the event loop whenever data has been received by the network connection. Simply pass onto the WebSocket driver to process and determine content boundaries. Required EventMachine::Connection interface



64
65
66
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 64

def receive_data(data)
  driver.parse(data)
end

#ssl_handshake_completedObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



115
116
117
118
119
120
121
122
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 115

def ssl_handshake_completed
  unless OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
    disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate"
    false
  else
    true
  end
end

#ssl_verify_peer(cert_string) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TLS verification support, original implementation by Mislav Marohnić:

github.com/lostisland/faraday/commit/63cf47c95b573539f047c729bd9ad67560bc83ff



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 88

def ssl_verify_peer(cert_string)
  cert = nil
  begin
    cert = OpenSSL::X509::Certificate.new(cert_string)
  rescue OpenSSL::X509::CertificateError => e
    disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate: #{e.message}"
    return false
  end

  @last_seen_cert = cert

  if certificate_store.verify(@last_seen_cert)
    begin
      certificate_store.add_cert(@last_seen_cert)
    rescue OpenSSL::X509::StoreError => e
      unless e.message == 'cert already in hash table'
        disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate: #{e.message}"
        return false
      end
    end
    true
  else
    disconnect_with_reason "Websocket host '#{host}' returned an invalid TLS certificate"
    false
  end
end

#unbindObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called whenever a connection (either a server or client connection) is closed Required EventMachine::Connection interface



70
71
72
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 70

def unbind
  change_state STATE.Disconnected, reason_closed || 'Websocket connection closed unexpectedly'
end

#urlObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

URL end point including initialization configuration WebSocket::Driver interface



76
77
78
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 76

def url
  @url
end

#write(data) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

WebSocket::Driver interface



81
82
83
# File 'lib/ably/realtime/connection/websocket_transport.rb', line 81

def write(data)
  send_data(data)
end