Class: EventMachine::WebSocket::Connection

Inherits:
Connection
  • Object
show all
Includes:
Debugger
Defined in:
lib/em-websocket/connection.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Connection

Returns a new instance of Connection.



29
30
31
32
33
34
35
36
37
# File 'lib/em-websocket/connection.rb', line 29

def initialize(options)
  @options = options
  @debug = options[:debug] || false
  @secure = options[:secure] || false
  @tls_options = options[:tls_options] || {}
  @data = ''

  debug [:initialize]
end

Instance Method Details

#close_websocket(code = nil, body = nil) ⇒ Object

Use this method to close the websocket connection cleanly This sends a close frame and waits for acknowlegement before closing the connection



42
43
44
45
46
47
48
49
50
51
# File 'lib/em-websocket/connection.rb', line 42

def close_websocket(code = nil, body = nil)
  if code && !(4000..4999).include?(code)
    raise "Application code may only use codes in the range 4000-4999"
  end

  # If code not defined then set to 1000 (normal closure)
  code ||= 1000

  close_websocket_private(code, body)
end

#dispatch(data) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/em-websocket/connection.rb', line 93

def dispatch(data)
  if data.match(/\A<policy-file-request\s*\/>/)
    send_flash_cross_domain_file
    return false
  else
    debug [:inbound_headers, data]
    @data << data
    @handler = HandlerFactory.build(self, @data, @secure, @debug)
    unless @handler
      # The whole header has not been received yet.
      return false
    end
    @data = nil
    @handler.run
    return true
  end
end

#onclose(&blk) ⇒ Object



10
# File 'lib/em-websocket/connection.rb', line 10

def onclose(&blk);    @onclose = blk;   end

#onerror(&blk) ⇒ Object



11
# File 'lib/em-websocket/connection.rb', line 11

def onerror(&blk);    @onerror = blk;   end

#onmessage(&blk) ⇒ Object



12
# File 'lib/em-websocket/connection.rb', line 12

def onmessage(&blk);  @onmessage = blk; end

#onopen(&blk) ⇒ Object

define WebSocket callbacks



9
# File 'lib/em-websocket/connection.rb', line 9

def onopen(&blk);     @onopen = blk;    end

#post_initObject



53
54
55
# File 'lib/em-websocket/connection.rb', line 53

def post_init
  start_tls(@tls_options) if @secure
end

#receive_data(data) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/em-websocket/connection.rb', line 57

def receive_data(data)
  debug [:receive_data, data]

  if @handler
    @handler.receive_data(data)
  else
    dispatch(data)
  end
rescue HandshakeError => e
  debug [:error, e]
  trigger_on_error(e)
  # Errors during the handshake require the connection to be aborted
  abort
rescue WebSocketError => e
  debug [:error, e]
  trigger_on_error(e)
  close_websocket_private(1002) # 1002 indicates a protocol error
rescue => e
  debug [:error, e]
  # These are application errors - raise unless onerror defined
  trigger_on_error(e) || raise(e)
  # There is no code defined for application errors, so use 3000
  # (which is reserved for frameworks)
  close_websocket_private(3000)
end

#requestObject



130
131
132
# File 'lib/em-websocket/connection.rb', line 130

def request
  @handler ? @handler.request : {}
end

#send(data) ⇒ Object



122
123
124
125
126
127
128
# File 'lib/em-websocket/connection.rb', line 122

def send(data)
  if @handler
    @handler.send_text_frame(data)
  else
    raise WebSocketError, "Cannot send data before onopen callback"
  end
end

#send_flash_cross_domain_fileObject



111
112
113
114
115
116
117
118
119
120
# File 'lib/em-websocket/connection.rb', line 111

def send_flash_cross_domain_file
  file =  '<?xml version="1.0"?><cross-domain-policy><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>'
  debug [:cross_domain, file]
  send_data file

  # handle the cross-domain request transparently
  # no need to notify the user about this connection
  @onclose = nil
  close_connection_after_writing
end

#stateObject



134
135
136
# File 'lib/em-websocket/connection.rb', line 134

def state
  @handler ? @handler.state : :handshake
end

#trigger_on_closeObject



20
21
22
# File 'lib/em-websocket/connection.rb', line 20

def trigger_on_close
  @onclose.call if @onclose
end

#trigger_on_error(reason) ⇒ Object



23
24
25
26
27
# File 'lib/em-websocket/connection.rb', line 23

def trigger_on_error(reason)
  return false unless @onerror
  @onerror.call(reason)
  true
end

#trigger_on_message(msg) ⇒ Object



14
15
16
# File 'lib/em-websocket/connection.rb', line 14

def trigger_on_message(msg)
  @onmessage.call(msg) if @onmessage
end

#trigger_on_openObject



17
18
19
# File 'lib/em-websocket/connection.rb', line 17

def trigger_on_open
  @onopen.call if @onopen
end

#unbindObject



83
84
85
86
87
88
89
90
91
# File 'lib/em-websocket/connection.rb', line 83

def unbind
  debug [:unbind, :connection]

  @handler.unbind if @handler
rescue => e
  debug [:error, e]
  # These are application errors - raise unless onerror defined
  trigger_on_error(e) || raise(e)
end