Class: Tubesock
- Inherits:
-
Object
- Object
- Tubesock
- Defined in:
- lib/tubesock.rb,
lib/tubesock/version.rb
Overview
Easily interact with WebSocket connections over Rack. TODO: Example with pure Rack
Defined Under Namespace
Modules: Hijack
Constant Summary collapse
- HijackNotAvailable =
Class.new RuntimeError
- VERSION =
"0.2.7"
Class Method Summary collapse
Instance Method Summary collapse
- #close ⇒ Object
- #close! ⇒ Object
- #closed? ⇒ Boolean
-
#initialize(socket, version) ⇒ Tubesock
constructor
A new instance of Tubesock.
- #keepalive ⇒ Object
- #listen ⇒ Object
- #onclose(&block) ⇒ Object
- #onerror(&block) ⇒ Object
- #onmessage(&block) ⇒ Object
- #onopen(&block) ⇒ Object
- #prevent_close_on_error ⇒ Object
- #send_data(data, type = :text) ⇒ Object
Constructor Details
#initialize(socket, version) ⇒ Tubesock
Returns a new instance of Tubesock.
10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/tubesock.rb', line 10 def initialize(socket, version) @socket = socket @version = version @open_handlers = [] @message_handlers = [] @close_handlers = [] @error_handlers = [] @close_on_error = true @active = true end |
Class Method Details
.hijack(env) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/tubesock.rb', line 24 def self.hijack(env) if env['rack.hijack'] env['rack.hijack'].call socket = env['rack.hijack_io'] handshake = WebSocket::Handshake::Server.new handshake.from_rack env socket.write handshake.to_s self.new socket, handshake.version else raise Tubesock::HijackNotAvailable end end |
Instance Method Details
#close ⇒ Object
93 94 95 96 97 98 99 100 |
# File 'lib/tubesock.rb', line 93 def close return unless @active @close_handlers.each(&:call) close! @active = false end |
#close! ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/tubesock.rb', line 102 def close! if @socket.respond_to?(:closed?) @socket.close unless @socket.closed? else @socket.close end end |
#closed? ⇒ Boolean
110 111 112 |
# File 'lib/tubesock.rb', line 110 def closed? @socket.closed? end |
#keepalive ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/tubesock.rb', line 114 def keepalive thread = Thread.new do Thread.current.abort_on_exception = true loop do sleep 5 send_data nil, :ping end end onclose do thread.kill end end |
#listen ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/tubesock.rb', line 71 def listen keepalive Thread.new do Thread.current.abort_on_exception = true begin @open_handlers.each(&:call) each_frame do |data| @message_handlers.each do |h| begin h.call(data) rescue => e @error_handlers.each{|eh| eh.call(e,data)} close if @close_on_error end end end ensure close end end end |
#onclose(&block) ⇒ Object
63 64 65 |
# File 'lib/tubesock.rb', line 63 def onclose(&block) @close_handlers << block end |
#onerror(&block) ⇒ Object
67 68 69 |
# File 'lib/tubesock.rb', line 67 def onerror(&block) @error_handlers << block end |
#onmessage(&block) ⇒ Object
59 60 61 |
# File 'lib/tubesock.rb', line 59 def (&block) @message_handlers << block end |
#onopen(&block) ⇒ Object
55 56 57 |
# File 'lib/tubesock.rb', line 55 def onopen(&block) @open_handlers << block end |
#prevent_close_on_error ⇒ Object
40 41 42 |
# File 'lib/tubesock.rb', line 40 def prevent_close_on_error @close_on_error = false end |
#send_data(data, type = :text) ⇒ Object
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/tubesock.rb', line 44 def send_data data, type = :text frame = WebSocket::Frame::Outgoing::Server.new( version: @version, data: data, type: type ) @socket.write frame.to_s rescue IOError, Errno::EPIPE, Errno::ETIMEDOUT close end |