Class: Midori::WebSocket
- Inherits:
-
Object
- Object
- Midori::WebSocket
- Defined in:
- lib/midori/websocket.rb,
ext/midori/websocket.c
Overview
This class provides methods for WebSocket connection instance.
Instance Attribute Summary collapse
-
#connection ⇒ Midori::Connection
raw EventMachine connection.
-
#events ⇒ Hash
response for different event.
-
#msg ⇒ Array<Integer>, String
message send from client.
-
#opcode ⇒ Integer
operation code of WebSocket.
-
#request ⇒ Midori::Request
raw request.
Instance Method Summary collapse
-
#close ⇒ Object
Close a websocket connection.
-
#decode(data) ⇒ Object
Decode raw data send from client.
-
#decode_mask(data) ⇒ Object
Decode masked message send from client.
-
#heartbeat(method, str) ⇒ Object
Ancestor of ping pong.
-
#initialize(connection) ⇒ WebSocket
constructor
Init a WebSocket instance with a connection.
-
#on(event) { ... } ⇒ Object
API definition for events.
-
#ping(str) ⇒ Object
Send a Ping request.
-
#pong(str) ⇒ Object
Send a Pong request.
-
#send(msg) ⇒ Object
Send data.
Constructor Details
#initialize(connection) ⇒ WebSocket
Init a WebSocket instance with a connection
13 14 15 16 |
# File 'lib/midori/websocket.rb', line 13 def initialize(connection) @events = {} @connection = connection end |
Instance Attribute Details
#connection ⇒ Midori::Connection
raw EventMachine connection
8 9 10 |
# File 'lib/midori/websocket.rb', line 8 def connection @connection end |
#events ⇒ Hash
response for different event
8 9 10 |
# File 'lib/midori/websocket.rb', line 8 def events @events end |
#msg ⇒ Array<Integer>, String
message send from client
8 9 10 |
# File 'lib/midori/websocket.rb', line 8 def msg @msg end |
#opcode ⇒ Integer
operation code of WebSocket
8 9 10 |
# File 'lib/midori/websocket.rb', line 8 def opcode @opcode end |
#request ⇒ Midori::Request
raw request
8 9 10 |
# File 'lib/midori/websocket.rb', line 8 def request @request end |
Instance Method Details
#close ⇒ Object
Close a websocket connection
105 106 107 |
# File 'lib/midori/websocket.rb', line 105 def close raise Midori::Exception::FrameEnd end |
#decode(data) ⇒ Object
Decode raw data send from client
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/midori/websocket.rb', line 20 def decode(data) # Fin and Opcode byte_tmp = data.getbyte fin = byte_tmp & 0b10000000 @opcode = byte_tmp & 0b00001111 # NOT Support Multiple Fragments raise Midori::Exception::ContinuousFrame unless fin raise Midori::Exception::OpCodeError unless [0x1, 0x2, 0x8, 0x9, 0xA].include? @opcode close if @opcode == 0x8 # Close Frame # return if @opcode == 0x9 || @opcode == 0xA # Ping Pong decode_mask(data) end |
#decode_mask(data) ⇒ Object
Decode masked message send from client
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/midori/websocket.rb', line 35 def decode_mask(data) # Mask byte_tmp = data.getbyte is_masked = byte_tmp & 0b10000000 raise Midori::Exception::NotMasked unless is_masked == 128 # Payload payload = byte_tmp & 0b01111111 mask = Array.new(4) { data.getbyte } # Message masked_msg = Array.new(payload) { data.getbyte } if [0x1, 0x9, 0xA].include? opcode @msg = mask_str(masked_msg, mask) else # [0x2] @msg = mask(masked_msg, mask) end # For debug # data.rewind # data.bytes {|byte| puts byte.to_s(16)} end |
#heartbeat(method, str) ⇒ Object
Ancestor of ping pong
99 100 101 102 |
# File 'lib/midori/websocket.rb', line 99 def heartbeat(method, str) raise Midori::Exception::PingPongSizeTooLarge if str.size > 125 @connection.send_data [method, str.size, str].pack("CCA#{str.size}") end |
#on(event) { ... } ⇒ Object
API definition for events
64 65 66 |
# File 'lib/midori/websocket.rb', line 64 def on(event, &block) # open, message, close, ping, pong @events[event] = block end |
#ping(str) ⇒ Object
Send a Ping request
86 87 88 |
# File 'lib/midori/websocket.rb', line 86 def ping(str) heartbeat(0b10001001, str) end |
#pong(str) ⇒ Object
Send a Pong request
92 93 94 |
# File 'lib/midori/websocket.rb', line 92 def pong(str) heartbeat(0b10001010, str) end |
#send(msg) ⇒ Object
Send data
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/midori/websocket.rb', line 70 def send(msg) output = [] if msg.is_a?String output << 0b10000001 << msg.size << msg @connection.send_data(output.pack("CCA#{msg.size}")) elsif msg.is_a? Array output << 0b10000010 << msg.size output.concat msg @connection.send_data(output.pack('C*')) else raise Midori::Exception::OpCodeError end end |