Class: Rocket::WebSocket
- Inherits:
-
Object
- Object
- Rocket::WebSocket
- Defined in:
- lib/rocket/websocket.rb
Defined Under Namespace
Classes: Error
Class Attribute Summary collapse
-
.debug ⇒ Object
Returns the value of attribute debug.
Instance Attribute Summary collapse
-
#header ⇒ Object
readonly
Returns the value of attribute header.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Instance Method Summary collapse
-
#close ⇒ Object
Does closing handshake.
- #close_socket ⇒ Object
- #host ⇒ Object
-
#initialize(arg, params = {}) ⇒ WebSocket
constructor
A new instance of WebSocket.
- #origin ⇒ Object
- #receive ⇒ Object
- #send(data) ⇒ Object
- #tcp_socket ⇒ Object
Constructor Details
#initialize(arg, params = {}) ⇒ WebSocket
Returns a new instance of WebSocket.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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 67 68 69 70 71 72 73 74 75 |
# File 'lib/rocket/websocket.rb', line 22 def initialize(arg, params = {}) uri = arg.is_a?(String) ? URI.parse(arg) : arg if uri.scheme == "ws" default_port = 80 elsif uri.scheme = "wss" default_port = 443 else raise(WebSocket::Error, "unsupported scheme: #{uri.scheme}") end @path = (uri.path.empty? ? "/" : uri.path) + (uri.query ? "?" + uri.query : "") host = uri.host + (uri.port == default_port ? "" : ":#{uri.port}") origin = params[:origin] || "http://#{uri.host}" key1 = generate_key() key2 = generate_key() key3 = generate_key3() socket = TCPSocket.new(uri.host, uri.port || default_port) if uri.scheme == "ws" @socket = socket else @socket = ssl_handshake(socket) end write( "GET #{@path} HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: Upgrade\r\n" + "Host: #{host}\r\n" + "Origin: #{origin}\r\n" + "Sec-WebSocket-Key1: #{key1}\r\n" + "Sec-WebSocket-Key2: #{key2}\r\n" + "\r\n" + "#{key3}") flush() line = gets().chomp() raise(WebSocket::Error, "bad response: #{line}") if !(line =~ /\AHTTP\/1.1 101 /n) read_header() if @header["Sec-WebSocket-Origin"] != origin raise(WebSocket::Error, "origin doesn't match: '#{@header["WebSocket-Origin"]}' != '#{origin}'") end reply_digest = read(16) expected_digest = security_digest(key1, key2, key3) if reply_digest != expected_digest raise(WebSocket::Error, "security digest doesn't match: %p != %p" % [reply_digest, expected_digest]) end @handshaked = true @closing_started = false end |
Class Attribute Details
.debug ⇒ Object
Returns the value of attribute debug.
16 17 18 |
# File 'lib/rocket/websocket.rb', line 16 def debug @debug end |
Instance Attribute Details
#header ⇒ Object (readonly)
Returns the value of attribute header.
19 20 21 |
# File 'lib/rocket/websocket.rb', line 19 def header @header end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
20 21 22 |
# File 'lib/rocket/websocket.rb', line 20 def path @path end |
Instance Method Details
#close ⇒ Object
Does closing handshake.
119 120 121 122 123 124 |
# File 'lib/rocket/websocket.rb', line 119 def close() return if @closing_started write("\xff\x00") @socket.close() if !@server @closing_started = true end |
#close_socket ⇒ Object
126 127 128 |
# File 'lib/rocket/websocket.rb', line 126 def close_socket() @socket.close() end |
#host ⇒ Object
110 111 112 |
# File 'lib/rocket/websocket.rb', line 110 def host return @header["Host"] end |
#origin ⇒ Object
114 115 116 |
# File 'lib/rocket/websocket.rb', line 114 def origin return @header["Origin"] end |
#receive ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/rocket/websocket.rb', line 86 def receive() if !@handshaked raise(WebSocket::Error, "call WebSocket\#handshake first") end packet = gets("\xff") return nil if !packet if packet =~ /\A\x00(.*)\xff\z/nm return force_encoding($1, "UTF-8") elsif packet == "\xff" && read(1) == "\x00" # closing if @server @socket.close() else close() end return nil else raise(WebSocket::Error, "input must be either '\\x00...\\xff' or '\\xff\\x00'") end end |
#send(data) ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'lib/rocket/websocket.rb', line 77 def send(data) if !@handshaked raise(WebSocket::Error, "call WebSocket\#handshake first") end data = force_encoding(data.dup(), "ASCII-8BIT") write("\x00#{data}\xff") flush() end |
#tcp_socket ⇒ Object
106 107 108 |
# File 'lib/rocket/websocket.rb', line 106 def tcp_socket return @socket end |