Class: EventMachine::JsonRPC::Client

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

Defined Under Namespace

Classes: Request

Constant Summary collapse

DEFAULT_REQUEST_TIMEOUT =
2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, port, request_timeout = nil, parser_options = {}) ⇒ Client

Returns a new instance of Client.



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
# File 'lib/em-jsonrpc/client.rb', line 8

def initialize(host, port, request_timeout = nil, parser_options = {})
  @host = host
  @port = port
  @request_timeout = request_timeout || DEFAULT_REQUEST_TIMEOUT
  @parser_options = parser_options

  if parser_options and parser_options[:symbolize_keys]
    @key_jsonrpc = :jsonrpc
    @key_id = :id
    @key_result = :result
    @key_error = :error
    @key_code = :code
    @key_message = :message
  else
    @key_jsonrpc = KEY_JSONRPC
    @key_id = KEY_ID
    @key_result = KEY_RESULT
    @key_error = KEY_ERROR
    @key_code = KEY_CODE
    @key_message = KEY_MESSAGE
  end

  @pending_requests = {}
  @connected = false
end

Instance Attribute Details

#pending_requestsObject (readonly)

Returns the value of attribute pending_requests.



6
7
8
# File 'lib/em-jsonrpc/client.rb', line 6

def pending_requests
  @pending_requests
end

Instance Method Details

#cancel_pending_requests(description) ⇒ Object



152
153
154
155
156
157
# File 'lib/em-jsonrpc/client.rb', line 152

def cancel_pending_requests description
  @pending_requests.each_value do |request|
    request.fail :canceled, "request canceled: #{description}"
  end
  @pending_requests.clear
end

#connect_againObject



70
71
72
# File 'lib/em-jsonrpc/client.rb', line 70

def connect_again
  reconnect @host, @port
end

#connected?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/em-jsonrpc/client.rb', line 57

def connected?
  @connected
end

#connection_completedObject



38
39
40
41
42
43
44
# File 'lib/em-jsonrpc/client.rb', line 38

def connection_completed
  @connected = true
  @parser = Yajl::Parser.new  @parser_options
  @parser.on_parse_complete = method(:obj_parsed)
  @state = :data
  ready
end

#connection_failedObject



64
65
# File 'lib/em-jsonrpc/client.rb', line 64

def connection_failed
end

#connection_terminatedObject



67
68
# File 'lib/em-jsonrpc/client.rb', line 67

def connection_terminated
end

#obj_parsed(obj) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/em-jsonrpc/client.rb', line 112

def obj_parsed(obj)
  case obj
  when Hash
    process(obj)
  when Array
    # Do nothing, just ignore.
  end
end

#parse_data(data) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/em-jsonrpc/client.rb', line 100

def parse_data(data)
  begin
    @parser << data
  rescue Yajl::ParseError => e
    close_connection
    @connected = false
    @state = :ignore
    parsing_error
    cancel_pending_requests "response parsing error"
  end
end

#parsing_errorObject



149
150
# File 'lib/em-jsonrpc/client.rb', line 149

def parsing_error
end

#post_initObject



34
35
36
# File 'lib/em-jsonrpc/client.rb', line 34

def post_init
  @encoder = Yajl::Encoder.new
end

#process(obj) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/em-jsonrpc/client.rb', line 121

def process(obj)
  return unless (id = obj[@key_id]) and id.is_a? String
  return unless request = @pending_requests[id]

  request.delete

  unless obj[@key_jsonrpc] == "2.0"
    request.fail :invalid_response, "invalid response: doesn't include \"jsonrpc\": \"2.0\""
    return
  end

  if obj.has_key? @key_result
    request.succeed obj[@key_result]
    return
  elsif error = obj[@key_error]
    if error.is_a? Hash and (code = error[@key_code]) and (message = error[@key_message])
      request.fail :error, error
      return
    else
      request.fail :invalid_response, "invalid response: \"error\" is not a valid object"
      return
    end
  else
    request.fail :invalid_response, "invalid response: not valid \"result\" or \"error\""
    return
  end
end

#readyObject



61
62
# File 'lib/em-jsonrpc/client.rb', line 61

def ready
end

#receive_data(data) ⇒ Object



91
92
93
94
95
96
97
98
# File 'lib/em-jsonrpc/client.rb', line 91

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

#send_request(method, params = nil) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/em-jsonrpc/client.rb', line 74

def send_request(method, params=nil)
  id = SecureRandom.hex 4
  request = Request.new self, id
  request.timeout @request_timeout
  @pending_requests[id] = request

  jsonrpc_request = {
    KEY_JSONRPC => VALUE_VERSION,
    KEY_ID => id,
    KEY_METHOD => method
  }
  jsonrpc_request[KEY_PARAMS] = params if params
  send_data @encoder.encode jsonrpc_request

  return request
end

#unbindObject



46
47
48
49
50
51
52
53
54
55
# File 'lib/em-jsonrpc/client.rb', line 46

def unbind
  @pending_requests.clear

  if @connected
    connection_terminated
  else
    connection_failed
  end
  @connected = false
end