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.



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

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

Instance Attribute Details

#wsObject (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



84
85
86
87
88
89
# File 'lib/bixby-common/websocket/api_channel.rb', line 84

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

#connected?Boolean

Handle channel events

Returns:

  • (Boolean)


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

def connected?
  @connected
end

#execute(json_request) ⇒ JsonResponse

Execute the given request (synchronously)

Parameters:

Returns:



32
33
34
# File 'lib/bixby-common/websocket/api_channel.rb', line 32

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



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/bixby-common/websocket/api_channel.rb', line 41

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

  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)

  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:



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

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



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/bixby-common/websocket/api_channel.rb', line 94

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
    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



77
78
79
# File 'lib/bixby-common/websocket/api_channel.rb', line 77

def open(event)
  @connected = true
end