class Bixby::WebSocket::APIChannel
WebSocket
API channel
Implements a simple request/response interface over a WebSocket
channel. Requests can be sent in either direction, in a sync or async manner.
Attributes
ws[R]
Public Class Methods
new(ws, handler, thread_pool)
click to toggle source
# File lib/bixby-common/websocket/api_channel.rb, line 18 def initialize(ws, handler, thread_pool) @ws = ws @handler = handler @responses = {} @connected = false @thread_pool = thread_pool end
Public Instance Methods
close(event)
click to toggle source
Close
Can be fired either due to disconnection or failure to connect
# File lib/bixby-common/websocket/api_channel.rb, line 88 def close(event) if event && !event.target.kind_of?(Faye::WebSocket::Client) then logger.debug { "closed connection from #{event.target.env["REMOTE_ADDR"]} (code=#{event.code}; reason=\"#{event.reason}\")" } end if @connected then @connected = false @handler.new(nil).disconnect(self) end end
connected?()
click to toggle source
Handle channel events
# File lib/bixby-common/websocket/api_channel.rb, line 73 def connected? @connected end
execute(json_request)
click to toggle source
Execute the given request (synchronously)
@param [JsonRequest] json_request
@return [JsonResponse] response
# File lib/bixby-common/websocket/api_channel.rb, line 33 def execute(json_request) fetch_response( execute_async(json_request) ) end
execute_async(json_request, &block)
click to toggle source
Execute the given request (asynchronously)
@param [JsonRequest] json_request
@return [String] request id
# File lib/bixby-common/websocket/api_channel.rb, line 42 def execute_async(json_request, &block) if json_request.kind_of? Request then id, request = json_request.id, json_request else request = Request.new(json_request) id = request.id end @responses[id] = AsyncResponse.new(id, &block) logger.debug { request.type == "connect" ? "execute_async: CONNECT [#{id}]" : "execute_async: RPC [#{id}]\n#{request.to_s}" } EM.next_tick { ws.send(request.to_wire) } id end
fetch_response(id)
click to toggle source
Fetch the response for the given request
@param [String] request id
@return [JsonResponse]
# File lib/bixby-common/websocket/api_channel.rb, line 64 def fetch_response(id) res = @responses[id].response @responses.delete(id) res end
message(event)
click to toggle source
Fired whenever a message is received on the channel
# File lib/bixby-common/websocket/api_channel.rb, line 101 def message(event) req = Message.from_wire(event.data) if req.type == "rpc" then # Execute the requested method and return the result # Do it asynchronously so as not to hold up the EM-loop while the command is running @thread_pool.perform do json_req = req.json_request logger.debug { "RPC request\n#{json_req}" } json_response = @handler.new(req).handle(json_req) EM.next_tick { ws.send(Response.new(json_response, req.id).to_wire) } end elsif req.type == "rpc_result" then # Pass the result back to the caller res = req.json_response logger.debug { "RPC_RESULT for request id [#{req.id}]\n#{res}" } @responses[req.id].response = res elsif req.type == "connect" then # Agent request to CONNECT to the manager # will only be received by the server-end of the channel logger.debug { "CONNECT request #{req.id}"} ret = @handler.new(req).connect(req.json_request, self) if ret.kind_of? JsonResponse then ws.send(Response.new(ret, req.id).to_wire) else ws.send(Response.new(JsonResponse.new("success"), req.id).to_wire) end end end
open(event)
click to toggle source
Open
# File lib/bixby-common/websocket/api_channel.rb, line 78 def open(event) if event && !event.target.kind_of?(Faye::WebSocket::Client) then logger.debug { "opened connection from #{event.target.env["REMOTE_ADDR"]}" } end @connected = true end