Class: Appium::Core::WebSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/appium_lib_core/common/ws/websocket.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url:, protocols: nil, options: {}) ⇒ WebSocket

A websocket client based on Faye::WebSocket::Client . Uses eventmachine to wait response from the peer. The eventmachine works on a thread. The thread will exit with close method.

Examples:

ws = WebSocket.new(url: "ws://#{host}:#{port}/ws/session/#{@session_id}/appium/device/logcat")
ws.client #=> #<Faye::WebSocket::Client:.....> # An instance of Faye::WebSocket::Client
ws.message 'some message' #=> nil. Send a message to the peer.
ws.close #=> Kill the thread which run a eventmachine.

Parameters:

  • url (String)

    URL to establish web socket connection. If the URL has no port, the client use: `ws`: 80, `wss`: 443 ports.

  • protocols (Array)

    An array of strings representing acceptable subprotocols for use over the socket. The driver will negotiate one of these to use via the Sec-WebSocket-Protocol header if supported by the other peer. Default is nil. The protocols is equal to github.com/faye/faye-websocket-ruby/ 's one for client.

  • options (Hash)

    Initialize options for Faye client. Read github.com/faye/faye-websocket-ruby#initialization-options for more details. Default is `{}`.


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
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 42

def initialize(url:, protocols: nil, options: {})
  @endpoint = url

  @ws_thread = Thread.new do
    EM.run do
      @client ||= ::Faye::WebSocket::Client.new(url, protocols, options)

      @client.on :open do |_open|
        handle_open
      end

      @client.on :message do |message|
        handle_message_data(message.data)
      end

      @client.on :error do |_error|
        handle_error
      end

      @client.on :close do |close|
        handle_close(close.code, close.reason)
      end
    end
  end
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client


21
22
23
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 21

def client
  @client
end

#endpointObject (readonly)

Returns the value of attribute endpoint


21
22
23
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 21

def endpoint
  @endpoint
end

Instance Method Details

#close(code: nil, reason: 'close from ruby_lib_core') ⇒ Object

Closes the connection, sending the given status code and reason text, both of which are optional.

Examples:

ws = WebSocket.new(url: "ws://#{host}:#{port}/ws/session/#{@session_id}/appium/device/logcat")
ws.close reason: 'a something special reason'

Parameters:

  • code (Integer)

    A status code to send to the peer with close signal. Default is nil.

  • reason (String)

    A reason to send to the peer with close signal. Default is 'close from ruby_lib_core'.


106
107
108
109
110
111
112
113
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 106

def close(code: nil, reason: 'close from ruby_lib_core')
  if @client.nil?
    ::Appium::Logger.warn 'Websocket was closed'
  else
    @client.close code, reason
  end
  @ws_thread.exit
end

#handle_close(code, reason) ⇒ Object

Fires when either the client or the server closes the connection. The method gets `code` and `reason` attributes. They expose the status code and message sent by the peer that closed the connection.

Default is just put a error message. The methods also clear `client` instance and stop the eventmachine which is called in initialising this class.


158
159
160
161
162
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 158

def handle_close(code, reason)
  ::Appium::Logger.debug %W(#{self.class} :close #{code} #{reason})
  @client = nil
  EM.stop
end

#handle_errorObject

Fires when there is a protocol error due to bad data sent by the other peer. This event is purely informational, you do not need to implement error recovery.

Default is just put a error message.


147
148
149
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 147

def handle_error
  ::Appium::Logger.error %W(#{self.class} :error)
end

#handle_message_data(data) ⇒ Object

Fires when the socket receives a message. The message gas one `data` attribute and this method can handle the data. The data is either a String (for text frames) or an Array of byte-sized integers (for binary frames).

Default is just put a debug message and puts the result on standard out. In general, users should override this handler to handle messages from the peer.


136
137
138
139
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 136

def handle_message_data(data)
  ::Appium::Logger.debug %W(#{self.class} :message #{data})
  $stdout << "#{data}\n"
end

#handle_openObject

Fires when the socket connection is established. Event has no attributes.

Default is just put a debug message.


122
123
124
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 122

def handle_open
  ::Appium::Logger.debug %W(#{self.class} :open)
end

#ping(message, &callback) ⇒ Object

Sends a ping frame with an optional message and fires the callback when a matching pong is received.

Examples:

ws = WebSocket.new(url: "ws://#{host}:#{port}/ws/session/#{@session_id}/appium/device/logcat")
ws.ping 'message'

Parameters:

  • message (String)

    A message to send ping.

  • callback (Block)

80
81
82
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 80

def ping(message, &callback)
  @client.ping message, &callback
end

#send(message) ⇒ Object

Accepts either a String or an Array of byte-sized integers and sends a text or binary message over the connection to the other peer; binary data must be encoded as an Array.

Examples:

ws = WebSocket.new(url: "ws://#{host}:#{port}/ws/session/#{@session_id}/appium/device/logcat")
ws.send 'happy testing'

Parameters:

  • message (String|Array)

    A message to send a text or binary message over the connection


93
94
95
# File 'lib/appium_lib_core/common/ws/websocket.rb', line 93

def send(message)
  @client.send message
end