Class: Anorexic::WSResponse

Inherits:
Object
  • Object
show all
Defined in:
lib/anorexic/server/protocols/ws_response.rb

Overview

this class handles WebSocket response.

the WSResponse supports only one method - the send method.

use: `response << data` to send data. data should be a String object.

the data wil be sent as text if the string is encoded as a UTF-8 string (default encoding). otherwise, the data will be sent as a binary stream.

todo: extentions support, support frames longer then 125 bytes.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request) ⇒ WSResponse


20
21
22
# File 'lib/anorexic/server/protocols/ws_response.rb', line 20

def initialize request
	@request, @service = request,request.service
end

Instance Attribute Details

#requestObject

the request.


18
19
20
# File 'lib/anorexic/server/protocols/ws_response.rb', line 18

def request
  @request
end

#serviceObject (readonly)

the service through which the response will be sent.


16
17
18
# File 'lib/anorexic/server/protocols/ws_response.rb', line 16

def service
  @service
end

Class Method Details

.frame_data(data, op_code = nil, fin = true) ⇒ Object

Dangerzone! ()alters the string, use `send` instead: formats the data as one or more WebSocket frames.


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/anorexic/server/protocols/ws_response.rb', line 49

def self.frame_data data, op_code = nil, fin = true
	# set up variables
	frame = ''.force_encoding('binary')
	op_code ||= data.encoding.name == 'UTF-8' ? 1 : 2
	data.force_encoding('binary')

	# fragment big data chuncks into smaller frames
	[frame << frame_data(data.slice!(0..1048576), op_code, false), op_code = 0] while data.length > 1048576

	# apply extenetions to the frame
	ext = 0
	# ext |= call each service.protocol.extenetions with data #changes data and returns flags to be set
	# service.protocol.extenetions.each { |ex| ext |= WSProtocol::SUPPORTED_EXTENTIONS[ex[0]][2].call data, ex[1..-1]}

	# set 
	frame << ( (fin ? 0b10000000 : 0) | (op_code & 0b00001111) | ext).chr

	if data.length < 125
		frame << data.length.chr
	elsif data.length.bit_length < 16					
		frame << 126.chr
		frame << [data.length].pack('S>')
	else
		frame << 127.chr
		frame << [data.length].pack('Q>')
	end
	frame << data
	frame
end

Instance Method Details

#<<(str) ⇒ Object

pushes data to the body of the response. this is the preffered way to add data to the response.


25
26
27
28
# File 'lib/anorexic/server/protocols/ws_response.rb', line 25

def << str
	service.send_nonblock self.class.frame_data(str.dup)
	self
end

#closeObject

sends any pending data and closes the connection.


43
44
45
46
# File 'lib/anorexic/server/protocols/ws_response.rb', line 43

def close
	service.send_nonblock self.class.frame_data('', 8)
	service.disconnect
end

#flushObject

makes sure any data held in the buffer is actually sent.


38
39
40
# File 'lib/anorexic/server/protocols/ws_response.rb', line 38

def flush
	service.flush
end

#send(str) ⇒ Object

sends the response object. headers will be frozen (they can only be sent at the head of the response).

the response will remain open for more data to be sent through (using `response << data` and `response.send`).


33
34
35
# File 'lib/anorexic/server/protocols/ws_response.rb', line 33

def send str
	service.send_nonblock self.class.frame_data(str.dup)
end