Class: Bixby::WebSocket::APIChannel

Inherits:
APIChannel show all
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

Instance Method Summary collapse

Methods included from Log

#log, setup_logger

Constructor Details

#initialize(ws, handler) ⇒ APIChannel

Returns a new instance of APIChannel.



16
17
18
19
20
21
# File 'lib/bixby-common/websocket/api_channel.rb', line 16

def initialize(ws, handler)
  @ws = ws
  @handler = handler
  @responses = {}
  @connected = false
end

Instance Attribute Details

#wsObject (readonly)

Returns the value of attribute ws.



14
15
16
# File 'lib/bixby-common/websocket/api_channel.rb', line 14

def ws
  @ws
end

Instance Method Details

#close(event) ⇒ Object

Close

Can be fired either due to disconnection or failure to connect



78
79
80
81
82
83
# File 'lib/bixby-common/websocket/api_channel.rb', line 78

def close(event)
  if @connected then
    @connected = false
    @handler.new(nil).disconnect(self)
  end
end

#connected?Boolean

Handle channel events

Returns:

  • (Boolean)


66
67
68
# File 'lib/bixby-common/websocket/api_channel.rb', line 66

def connected?
  @connected
end

#execute(json_request) ⇒ JsonResponse

Execute the given request (synchronously)

Parameters:

Returns:



30
31
32
# File 'lib/bixby-common/websocket/api_channel.rb', line 30

def execute(json_request)
  fetch_response( execute_async(json_request) )
end

#execute_async(json_request, &block) ⇒ String

Execute the given request (asynchronously)

Parameters:

Returns:

  • (String)

    request id



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bixby-common/websocket/api_channel.rb', line 39

def execute_async(json_request, &block)
  logger.debug { "execute_async:\n#{json_request.to_s}" }

  request = Request.new(json_request)
  id = request.id
  @responses[id] = AsyncResponse.new(id, &block)

  EM.next_tick {
    ws.send(request.to_wire)
  }
  id
end

#fetch_response(id) ⇒ JsonResponse

Fetch the response for the given request

Parameters:

  • request (String)

    id

Returns:



57
58
59
60
61
# File 'lib/bixby-common/websocket/api_channel.rb', line 57

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



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
# File 'lib/bixby-common/websocket/api_channel.rb', line 88

def message(event)
  req = Message.from_wire(event.data)
  logger.debug { "new '#{req.type}' message" }

  if req.type == "rpc" then
    # Execute the requested method and return the result
    json_req = req.json_request
    logger.debug { json_req.to_s }
    json_response = @handler.new(req).handle(json_req)

    # result = { :type => "rpc_result", :id => req.id, :data => json_response }
    # ws.send(MultiJson.dump(result))
    ws.send(Response.new(json_response, req.id).to_wire)

  elsif req.type == "rpc_result" then
    # Pass the result back to the caller
    res = req.json_response
    logger.debug { res.to_s }
    @responses[req.id].response = res

  elsif req.type == "connect" then
    @handler.new(req).connect(req.json_request, self)

  end
end

#open(event) ⇒ Object

Open



71
72
73
# File 'lib/bixby-common/websocket/api_channel.rb', line 71

def open(event)
  @connected = true
end