diff options
author | Matthew Draper <matthew@trebex.net> | 2016-01-21 14:59:11 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-01-24 22:52:40 +1030 |
commit | 322dca293b3716ccaa09e7e82046e539b0d2ffda (patch) | |
tree | 512383f2375ff948a085183c74c3da2848f58069 /actioncable/lib/action_cable/connection/stream.rb | |
parent | 68a9060d02b1eb35c12843c0f1653809b776b35b (diff) | |
download | rails-322dca293b3716ccaa09e7e82046e539b0d2ffda.tar.gz rails-322dca293b3716ccaa09e7e82046e539b0d2ffda.tar.bz2 rails-322dca293b3716ccaa09e7e82046e539b0d2ffda.zip |
Import the relevant portions of faye-websocket
(as adapted to use concurrent-ruby / nio4r instead of eventmachine)
Diffstat (limited to 'actioncable/lib/action_cable/connection/stream.rb')
-rw-r--r-- | actioncable/lib/action_cable/connection/stream.rb | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/actioncable/lib/action_cable/connection/stream.rb b/actioncable/lib/action_cable/connection/stream.rb new file mode 100644 index 0000000000..ace250cd16 --- /dev/null +++ b/actioncable/lib/action_cable/connection/stream.rb @@ -0,0 +1,59 @@ +module ActionCable + module Connection + #-- + # This class is heavily based on faye-websocket-ruby + # + # Copyright (c) 2010-2015 James Coglan + class Stream + def initialize(event_loop, socket) + @event_loop = event_loop + @socket_object = socket + @stream_send = socket.env['stream.send'] + + @rack_hijack_io = nil + + hijack_rack_socket + end + + def each(&callback) + @stream_send ||= callback + end + + def close + shutdown + @socket_object.client_gone + end + + def shutdown + clean_rack_hijack + end + + def write(data) + return @rack_hijack_io.write(data) if @rack_hijack_io + return @stream_send.call(data) if @stream_send + rescue EOFError + @socket_object.client_gone + end + + def receive(data) + @socket_object.parse(data) + end + + private + def hijack_rack_socket + return unless @socket_object.env['rack.hijack'] + + @socket_object.env['rack.hijack'].call + @rack_hijack_io = @socket_object.env['rack.hijack_io'] + + @event_loop.attach(@rack_hijack_io, self) + end + + def clean_rack_hijack + return unless @rack_hijack_io + @event_loop.detach(@rack_hijack_io, self) + @rack_hijack_io = nil + end + end + end +end |