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

def close(event)
  if @connected then
    logger.debug "client disconnected"
    @connected = false
    @handler.new(nil).disconnect(self)
  end
end

#connected?Boolean

Handle channel events

Returns:

  • (Boolean)


64
65
66
# File 'lib/bixby-common/websocket/api_channel.rb', line 64

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) ⇒ String

Execute the given request (asynchronously)

Parameters:

Returns:

  • (String)

    request id



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

def execute_async(json_request)
  request = Request.new(json_request)
  id = request.id
  @responses[id] = AsyncResponse.new(id)

  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:



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

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



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/bixby-common/websocket/api_channel.rb', line 89

def message(event)
  logger.debug "got a message:\n#{event.data}"
  req = Message.from_wire(event.data)

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

    # 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
    @responses[req.id].response = JsonResponse.from_json(req.body)

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

  end
end

#open(event) ⇒ Object

Open



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

def open(event)
  # TODO extract Agent ID, if Agent
  logger.debug "new channel opened"
  @connected = true
end