Class: SinatraWebsocket::Connection

Inherits:
EventMachine::WebSocket::Connection
  • Object
show all
Defined in:
lib/sinatra-websocket.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, socket, options = {}) ⇒ Connection

Overwrite initialize from em-websocket set all standard options and disable EM connection inactivity timeout


95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/sinatra-websocket.rb', line 95

def initialize(app, socket, options = {})
  @app     = app
  @socket  = socket
  @options = options
  @debug   = options[:debug] || false
  @ssl     = socket.backend.respond_to?(:ssl?) && socket.backend.ssl?

  socket.websocket = self
  socket.comm_inactivity_timeout = 0

  debug [:initialize]
end

Class Method Details

.async_responseObject

Standard async response


48
49
50
# File 'lib/sinatra-websocket.rb', line 48

def async_response
  [-1, {}, []]
end

.failure_responseObject

Standard 400 response


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

def failure_response
  [ 400, {'Content-Type' => 'text/plain'}, [ 'Bad request' ] ]
end

.from_env(env, options = {}) {|connection| ... } ⇒ Object

Yields:

  • (connection)

10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/sinatra-websocket.rb', line 10

def from_env(env, options = {})
  if env.include?('async.orig_callback')
    callback_key = 'async.orig_callback'
  elsif env.include?(Thin::Request::ASYNC_CALLBACK)
    callback_key = Thin::Request::ASYNC_CALLBACK
  else
    raise Error::ConfigurationError.new('Could not find an async callback in our environment!')
  end
  socket     = env[callback_key].receiver
  request    = request_from_env(env)
  connection = Connection.new(env, socket, :debug => options[:debug])
  yield(connection) if block_given?
  connection.dispatch(request) ? async_response : failure_response
end

.new(*args) ⇒ Object

Overwrite new from EventMachine we need to skip standard procedure called when socket is created - this is just a stub


66
67
68
69
70
# File 'lib/sinatra-websocket.rb', line 66

def self.new(*args)
  instance = allocate
  instance.__send__(:initialize, *args)
  instance
end

.request_from_env(env) ⇒ Object

Parse Rack env to em-websocket-compatible format this probably should be moved to Base in future


32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/sinatra-websocket.rb', line 32

def request_from_env(env)
  request = {}
  request['path']   = env['REQUEST_URI'].to_s
  request['method'] = env['REQUEST_METHOD']
  request['query']  = env['QUERY_STRING'].to_s
  request['Body']   = env['rack.input'].read

  env.each do |key, value|
    if key.match(/HTTP_(.+)/)
      request[$1.downcase.gsub('_','-')] ||= value
    end
  end
  request
end

Instance Method Details

#close_connection(*args) ⇒ Object

Overwrite close_connection from EventMachine delegate close_connection to rack server


82
83
84
85
86
# File 'lib/sinatra-websocket.rb', line 82

def close_connection(*args)
  EM.next_tick do
    @socket.close_connection(*args)
  end
end

#dispatch(data) ⇒ Object

Overwrite dispath from em-websocket we already have request headers parsed so we can skip it and call build_with_request


115
116
117
118
119
120
121
122
123
124
125
# File 'lib/sinatra-websocket.rb', line 115

def dispatch(data)
  return false if data.nil?
  debug [:inbound_headers, data]
  @handler = EventMachine::WebSocket::HandlerFactory.build_with_request(self, data, data['Body'], @ssl, @debug)
  unless @handler
    # The whole header has not been received yet.
    return false
  end
  @handler.run
  return true
end

#get_peernameObject


108
109
110
# File 'lib/sinatra-websocket.rb', line 108

def get_peername
  @socket.get_peername
end

#send_data(*args) ⇒ Object

Overwrite send_data from EventMachine delegate send_data to rack server


74
75
76
77
78
# File 'lib/sinatra-websocket.rb', line 74

def send_data(*args)
  EM.next_tick do
    @socket.send_data(*args)
  end
end