Class: ScalarRubyTest::Runtime::WebSocketConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/amritk-scalar-test/runtime.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(socket, request) ⇒ WebSocketConnection

Returns a new instance of WebSocketConnection.



114
115
116
117
# File 'lib/amritk-scalar-test/runtime.rb', line 114

def initialize(socket, request)
  @socket = socket
  @request = request
end

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



112
113
114
# File 'lib/amritk-scalar-test/runtime.rb', line 112

def request
  @request
end

#socketObject (readonly)

Returns the value of attribute socket.



112
113
114
# File 'lib/amritk-scalar-test/runtime.rb', line 112

def socket
  @socket
end

Instance Method Details

#closeObject



161
162
163
# File 'lib/amritk-scalar-test/runtime.rb', line 161

def close
  @socket.close unless @socket.closed?
end

#closed?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/amritk-scalar-test/runtime.rb', line 165

def closed?
  @socket.closed?
end

#receiveObject



140
141
142
143
# File 'lib/amritk-scalar-test/runtime.rb', line 140

def receive
  text = receive_text
  text.nil? ? nil : @request.deserialize_receive(text)
end

#receive_textObject



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/amritk-scalar-test/runtime.rb', line 145

def receive_text
  header = read_exact(2).bytes
  opcode = header[0] & 0x0f
  length_byte = header[1]
  masked = (length_byte & 0x80) != 0
  length = length_byte & 0x7f
  length = read_exact(2).unpack1("n") if length == 126
  length = read_exact(8).unpack1("Q>") if length == 127
  mask = masked ? read_exact(4).bytes : nil
  payload = read_exact(length)
  payload = payload.bytes.each_with_index.map { |byte, index| (byte ^ mask[index % 4]).chr }.join if mask
  return nil if opcode == 0x8
  raise WebSocketMessageError, "unsupported websocket frame opcode #{opcode}" unless opcode == 0x1
  payload.force_encoding("UTF-8")
end

#send(message) ⇒ Object



119
120
121
# File 'lib/amritk-scalar-test/runtime.rb', line 119

def send(message)
  send_text(@request.serialize_send(message))
end

#send_text(payload) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/amritk-scalar-test/runtime.rb', line 123

def send_text(payload)
  data = payload.to_s.b
  mask = SecureRandom.random_bytes(4)
  header = [0x81]
  if data.bytesize < 126
    header << (0x80 | data.bytesize)
  elsif data.bytesize < 65_536
    header << (0x80 | 126)
    header.concat([data.bytesize].pack("n").bytes)
  else
    header << (0x80 | 127)
    header.concat([data.bytesize].pack("Q>").bytes)
  end
  masked = data.bytes.each_with_index.map { |byte, index| (byte ^ mask.getbyte(index % 4)).chr }.join
  @socket.write(header.pack("C*") + mask + masked)
end