summaryrefslogtreecommitdiffstats
path: root/webchat/public/rpc.js
blob: 8e911e1d1ac2e03f8d9fe75ff982f2ee8c258a81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
try {
  module.exports = RPC
}
catch(e){
}

function RPC (transport) {
  this._id = 0
  this._waiting_callbacks = {}
  this._methods = {}
  this._transport = transport

  transport.onmessage = this.onmessage.bind(this)
}

RPC.prototype.register = function (method, params, callback) {
  this._methods[method] = callback
}

RPC.prototype.send = function (method, params, callback) {
  var message = {
    method: method,
    params: params,
  }
  if (callback) {
    var id = ++this._id
    this._waiting_callbacks[id] = callback
    message.id = id
  }
  return this._transport.send(message)
}

function _is_request (message) {
  return typeof message.method === 'string'
}

function _is_response (message) {
  return message.hasOwnProperty('result')
      || message.hasOwnProperty('error')
}

RPC.prototype.onmessage = function (message) {
  console.log('RPC message:', message)
  if (_is_request(message)) {
    return this._on_request(message)
  }
  if (_is_response(message)) {
    return this._on_response(message)
  }
  return this._on_bad_message(message)
}

RPC.prototype._on_request = function (request) {
  var method = this._methods[request.method] || function(){
    console.log('method not found', request.method)
  }
  var params = request.params
  var id = request.id

  var transport = this._transport

  if (typeof id === 'string' || typeof id === 'number' || id === null) {
    return method(params, function (error, result) {
      var response = {
        id: id,
      }
      if (error) {
        response.error = error
      } else {
        response.result = result
      }
      console.log('request:', request, '->', response)
      return transport.send(response)
    })
  } else {
    return method(params, function (error, result) {
      var response = {
        id: id,
      }
      if (error) {
        response.error = error
      } else {
        response.result = result
      }
      console.log('notification:', request, '->', response)
    })
  }
}

RPC.prototype._on_response = function (response) {
  var result = response.result
  var error = response.error
  var id = response.id

  var callback = this._waiting_callbacks[id]
  delete this._waiting_callbacks[id]

  return callback(result, error)
}