Class: FTW::WebSocket
- Inherits:
-
Object
- Object
- FTW::WebSocket
- Includes:
- Cabin::Inspectable, CRLF
- Defined in:
- lib/ftw/namespace.rb,
lib/ftw/websocket.rb
Overview
WebSockets, RFC6455.
TODO(sissel): Find a comfortable way to make this websocket stuff both use HTTP::Connection for the HTTP handshake and also be usable from HTTP::Client TODO(sissel): Also consider SPDY and the kittens.
Defined Under Namespace
Modules: Constants Classes: Parser, Rack, Writer
Constant Summary collapse
- TEXTFRAME =
The frame identifier for a ‘text’ frame
0x0001
- WEBSOCKET_ACCEPT_UUID =
Search RFC6455 for this string and you will find its definitions. It is used in servers accepting websocket upgrades.
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
Constants included from CRLF
Instance Method Summary collapse
-
#connection=(connection) ⇒ Object
Set the connection for this websocket.
-
#each(&block) ⇒ Object
Iterate over each WebSocket message.
-
#handshake_ok?(response) ⇒ Boolean
Is this Response acceptable for our WebSocket Upgrade request?.
-
#initialize(request) ⇒ WebSocket
constructor
Creates a new websocket and fills in the given http request with any necessary settings.
-
#publish(message) ⇒ Object
Publish a message text.
-
#receive ⇒ Object
Receive a single payload.
Constructor Details
#initialize(request) ⇒ WebSocket
Creates a new websocket and fills in the given http request with any necessary settings.
36 37 38 39 40 41 42 |
# File 'lib/ftw/websocket.rb', line 36 def initialize(request) @key_nonce = generate_key_nonce @request = request prepare(@request) @parser = FTW::WebSocket::Parser.new @messages = [] end |
Instance Method Details
#connection=(connection) ⇒ Object
Set the connection for this websocket. This is usually invoked by FTW::Agent after the websocket upgrade and handshake have been successful.
You probably don’t call this yourself.
48 49 50 |
# File 'lib/ftw/websocket.rb', line 48 def connection=(connection) @connection = connection end |
#each(&block) ⇒ Object
Iterate over each WebSocket message. This method will run forever unless you break from it.
The text payload of each message will be yielded to the block.
121 122 123 124 125 |
# File 'lib/ftw/websocket.rb', line 121 def each(&block) while true block.call(receive) end end |
#handshake_ok?(response) ⇒ Boolean
Is this Response acceptable for our WebSocket Upgrade request?
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ftw/websocket.rb', line 102 def handshake_ok?(response) # See RFC6455 section 4.2.2 return false unless response.status == 101 # "Switching Protocols" return false unless response.headers.get("upgrade").downcase == "websocket" return false unless response.headers.get("connection").downcase == "upgrade" # Now verify Sec-WebSocket-Accept. It should be the SHA-1 of the # Sec-WebSocket-Key (in base64) + WEBSOCKET_ACCEPT_UUID expected = @key_nonce + WEBSOCKET_ACCEPT_UUID expected_hash = Digest::SHA1.base64digest(expected) return false unless response.headers.get("Sec-WebSocket-Accept") == expected_hash return true end |
#publish(message) ⇒ Object
Publish a message text.
This will send a websocket text frame over the connection.
145 146 147 148 |
# File 'lib/ftw/websocket.rb', line 145 def publish() writer = FTW::WebSocket::Writer.singleton writer.write_text(@connection, ) end |
#receive ⇒ Object
Receive a single payload
128 129 130 131 |
# File 'lib/ftw/websocket.rb', line 128 def receive @messages += network_consume if @messages.empty? @messages.shift end |