class LiteCable::Server::ClientSocket::Base
Wrapper over web socket
Attributes
active[R]
close_on_error[R]
socket[R]
version[R]
Public Class Methods
new(env, socket, version)
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 13 def initialize(env, socket, version) log(:debug, "WebSocket version #{version}") @env = env @socket = socket @version = version @active = true @open_handlers = [] @message_handlers = [] @close_handlers = [] @error_handlers = [] @close_on_error = true end
Public Instance Methods
close()
click to toggle source
rubocop: enable Metrics/MethodLength
# File lib/lite_cable/server/client_socket/base.rb, line 90 def close return unless @active @close_handlers.each(&:call) close! @active = false end
closed?()
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 99 def closed? @socket.closed? end
listen()
click to toggle source
rubocop: disable Metrics/MethodLength
# File lib/lite_cable/server/client_socket/base.rb, line 68 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| h.call(data) rescue => e # rubocop: disable Style/RescueStandardError log(:error, "Socket receive failed: #{e}") @error_handlers.each { |eh| eh.call(e, data) } close if close_on_error end end ensure close end end end
onclose(&block)
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 59 def onclose(&block) @close_handlers << block end
onerror(&block)
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 63 def onerror(&block) @error_handlers << block end
onmessage(&block)
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 55 def onmessage(&block) @message_handlers << block end
onopen(&block)
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 51 def onopen(&block) @open_handlers << block end
prevent_close_on_error()
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 28 def prevent_close_on_error @close_on_error = false end
request()
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 47 def request @request ||= Rack::Request.new(@env) end
transmit(data, type: :text)
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 32 def transmit(data, type: :text) frame = WebSocket::Frame::Outgoing::Server.new( version: version, data: data, type: type ) socket.write frame.to_s rescue EOFError, Errno::ECONNRESET => e log(:debug, "Socket gone: #{e}") close rescue IOError, Errno::EPIPE, Errno::ETIMEDOUT => e log(:error, "Socket send failed: #{e}") close end
Private Instance Methods
close!()
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 107 def close! if @socket.respond_to?(:closed?) close_socket unless @socket.closed? else close_socket end end
close_socket()
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 115 def close_socket frame = WebSocket::Frame::Outgoing::Server.new(version: version, type: :close, code: 1000) @socket.write(frame.to_s) if frame.supported? @socket.close rescue IOError, Errno::EPIPE, Errno::ETIMEDOUT # rubocop:disable Lint/HandleExceptions # already closed end
each_frame() { |data| ... }
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 137 def each_frame framebuffer = WebSocket::Frame::Incoming::Server.new(version: version) while IO.select([socket]) data = socket.respond_to?(:recv) ? socket.recv(2000) : socket.readpartial(2000) break if data.empty? framebuffer << data while frame = framebuffer.next # rubocop:disable Lint/AssignmentInCondition case frame.type when :close return when :text, :binary yield frame.data end end end rescue Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNRESET, IOError, Errno::EBADF => e log(:debug, "Socket frame error: #{e}") nil # client disconnected or timed out end
keepalive()
click to toggle source
# File lib/lite_cable/server/client_socket/base.rb, line 123 def keepalive thread = Thread.new do Thread.current.abort_on_exception = true loop do sleep 5 transmit nil, type: :ping end end onclose do thread.kill end end