Class: Bixby::WebSocket::APIChannel
- Inherits:
-
APIChannel
- Object
- APIChannel
- Bixby::WebSocket::APIChannel
- Defined in:
- lib/bixby-common/websocket/api_channel.rb
Overview
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.
Instance Attribute Summary collapse
-
#ws ⇒ Object
readonly
Returns the value of attribute ws.
Instance Method Summary collapse
-
#close(event) ⇒ Object
Close.
-
#connected? ⇒ Boolean
Handle channel events.
-
#execute(json_request) ⇒ JsonResponse
Execute the given request (synchronously).
-
#execute_async(json_request, &block) ⇒ String
Execute the given request (asynchronously).
-
#fetch_response(id) ⇒ JsonResponse
Fetch the response for the given request.
-
#initialize(ws, handler, thread_pool) ⇒ APIChannel
constructor
A new instance of APIChannel.
-
#message(event) ⇒ Object
Message.
-
#open(event) ⇒ Object
Open.
Methods included from Log
bin_regex, clean_ex, clean_ex_for_console, console_appender?, gems_regex, #log, ruby_regex, setup_logger
Constructor Details
#initialize(ws, handler, thread_pool) ⇒ APIChannel
Returns a new instance of APIChannel.
18 19 20 21 22 23 24 |
# 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 |
Instance Attribute Details
#ws ⇒ Object (readonly)
Returns the value of attribute ws.
16 17 18 |
# File 'lib/bixby-common/websocket/api_channel.rb', line 16 def ws @ws end |
Instance Method Details
#close(event) ⇒ Object
Close
Can be fired either due to disconnection or failure to connect
88 89 90 91 92 93 94 95 96 |
# 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? ⇒ Boolean
Handle channel events
73 74 75 |
# File 'lib/bixby-common/websocket/api_channel.rb', line 73 def connected? @connected end |
#execute(json_request) ⇒ JsonResponse
Execute the given request (synchronously)
33 34 35 |
# 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) ⇒ String
Execute the given request (asynchronously)
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# 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) ⇒ JsonResponse
Fetch the response for the given request
64 65 66 67 68 |
# 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) ⇒ Object
Message
Fired whenever a message is received on the channel
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/bixby-common/websocket/api_channel.rb', line 101 def (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) ⇒ Object
Open
78 79 80 81 82 83 |
# 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 |