Class: EventMachine::JsonRPC::Server

Inherits:
EM::Connection
  • Object
show all
Defined in:
lib/em-jsonrpc/server.rb

Defined Under Namespace

Classes: Request

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*options) ⇒ Server

Returns a new instance of Server.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/em-jsonrpc/server.rb', line 6

def initialize(*options)
  parser_options = options.first || {}

  if parser_options[:symbolize_keys]
    @key_jsonrpc = :jsonrpc
    @key_id = :id
    @key_method = :method
    @key_params = :params
  else
    @key_jsonrpc = KEY_JSONRPC
    @key_id = KEY_ID
    @key_method = KEY_METHOD
    @key_params = KEY_PARAMS
  end

  @parser = Yajl::Parser.new parser_options
  @parser.on_parse_complete = method(:obj_parsed)

  @state = :data
end

Instance Attribute Details

#encoderObject (readonly)

Returns the value of attribute encoder.



4
5
6
# File 'lib/em-jsonrpc/server.rb', line 4

def encoder
  @encoder
end

Instance Method Details

#batch_not_supported_error(obj) ⇒ Object

This method could be overriden in the user’s inherited class.



130
131
132
# File 'lib/em-jsonrpc/server.rb', line 130

def batch_not_supported_error(obj)
  $stderr.puts "batch request received but not implemented"
end

#invalid_request(obj, code, message = nil) ⇒ Object

This method could be overriden in the user’s inherited class.



135
136
137
# File 'lib/em-jsonrpc/server.rb', line 135

def invalid_request(obj, code, message=nil)
  $stderr.puts "error #{code}: #{message}"
end

#obj_parsed(obj) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/em-jsonrpc/server.rb', line 47

def obj_parsed(obj)
  @encoder ||= Yajl::Encoder.new

  case obj
  # Individual request/notification.
  when Hash
    process(obj)
  # Batch: multiple requests/notifications in an array.
  # NOTE: Not implemented as it doesn't make sense using JSON RPC over pure TCP / UnixSocket.
  when Array
    send_data BATCH_NOT_SUPPORTED_RESPONSE
    close_connection_after_writing
    @state = :ignore
    batch_not_supported_error obj
  end
end

#parse_data(data) ⇒ Object



36
37
38
39
40
41
42
43
44
45
# File 'lib/em-jsonrpc/server.rb', line 36

def parse_data(data)
  begin
    @parser << data
  rescue Yajl::ParseError => e
    send_data PARSING_ERROR_RESPONSE
    close_connection_after_writing
    @state = :ignore
    parsing_error data, e
  end
end

#parsing_error(data, exception) ⇒ Object

This method could be overriden in the user’s inherited class.



125
126
127
# File 'lib/em-jsonrpc/server.rb', line 125

def parsing_error(data, exception)
  $stderr.puts "parsing error:\n#{exception.message}"
end

#process(obj) ⇒ Object



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
100
101
# File 'lib/em-jsonrpc/server.rb', line 64

def process(obj)
  is_request = obj.has_key?(@key_id)
  id = obj[@key_id]

  if is_request
    unless id.is_a? String or id.is_a? Fixnum or id.is_a? NilClass
      invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_ID
      reply_error nil, CODE_INVALID_REQUEST, MSG_INVALID_REQ_ID
      return false
    end
  end

  unless obj[@key_jsonrpc] == "2.0"
    invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_JSONRPC
    reply_error id, CODE_INVALID_REQUEST, MSG_INVALID_REQ_JSONRPC
    return false
  end

  unless (method = obj[@key_method]).is_a? String
    invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_METHOD
    reply_error id, CODE_INVALID_REQUEST, MSG_INVALID_REQ_METHOD
    return false
  end

  if (params = obj[@key_params])
    unless params.is_a? Array or params.is_a? Hash
      invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_PARAMS
      reply_error id, CODE_INVALID_REQUEST, MSG_INVALID_REQ_PARAMS
      return false
    end
  end

  if is_request
    receive_request Request.new(self, id, method, params)
  else
    receive_notification method, params
  end
end

#receive_data(data) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/em-jsonrpc/server.rb', line 27

def receive_data(data)
  case @state
  when :data
    parse_data(data)
  when :ignore
    nil
  end
end

#receive_notification(method, params) ⇒ Object

This method must be overriden in the user’s inherited class.



109
110
111
# File 'lib/em-jsonrpc/server.rb', line 109

def receive_notification(method, params)
  puts "notification received (method: #{method.inspect}, params: #{params.inspect})"
end

#receive_request(request) ⇒ Object

This method must be overriden in the user’s inherited class.



104
105
106
# File 'lib/em-jsonrpc/server.rb', line 104

def receive_request(request)
  puts "request received:\n#{request.inspect}"
end

#reply_error(id, code, message) ⇒ Object



113
114
115
116
117
118
119
120
121
122
# File 'lib/em-jsonrpc/server.rb', line 113

def reply_error(id, code, message)
  send_data @encoder.encode({
    KEY_JSONRPC => VALUE_VERSION,
    KEY_ID => id,
    KEY_ERROR => {
      KEY_CODE => code,
      KEY_MESSAGE => message
    }
  })
end