Class: AnyCable::Rack::Socket

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/anycable/rack/socket.rb

Overview

Socket wrapper

Constant Summary

Constants included from Logging

Logging::PREFIX

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, socket, version) ⇒ Socket

Returns a new instance of Socket.



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/anycable/rack/socket.rb', line 23

def initialize(env, socket, version)
  log(:debug, "WebSocket version #{version}")
  @env = env
  @socket = socket
  @version = version

  @_open_handlers = []
  @_message_handlers = []
  @_close_handlers = []
  @_error_handlers = []
  @_active = true
end

Instance Attribute Details

#socketObject (readonly)

Returns the value of attribute socket.



21
22
23
# File 'lib/anycable/rack/socket.rb', line 21

def socket
  @socket
end

#versionObject (readonly)

Returns the value of attribute version.



21
22
23
# File 'lib/anycable/rack/socket.rb', line 21

def version
  @version
end

Instance Method Details

#closeObject



91
92
93
94
95
96
97
98
# File 'lib/anycable/rack/socket.rb', line 91

def close
  return unless @_active

  @_close_handlers.each(&:call)
  close!

  @_active = false
end

#closed?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/anycable/rack/socket.rb', line 100

def closed?
  socket.closed?
end

#listenObject



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/anycable/rack/socket.rb', line 70

def listen
  keepalive
  Thread.new do
    Thread.current.report_on_exception = true
    begin
      @_open_handlers.each(&:call)
      each_frame do |data|
        @_message_handlers.each do |handler|
          handler.call(data)
        rescue => e # rubocop: disable Style/RescueStandardError
          log(:error, "Socket receive failed: #{e}")
          @_error_handlers.each { |eh| eh.call(e, data) }
          close
        end
      end
    ensure
      close
    end
  end
end

#onclose(&block) ⇒ Object



62
63
64
# File 'lib/anycable/rack/socket.rb', line 62

def onclose(&block)
  @_close_handlers << block
end

#onerror(&block) ⇒ Object



66
67
68
# File 'lib/anycable/rack/socket.rb', line 66

def onerror(&block)
  @_error_handlers << block
end

#onmessage(&block) ⇒ Object



58
59
60
# File 'lib/anycable/rack/socket.rb', line 58

def onmessage(&block)
  @_message_handlers << block
end

#onopen(&block) ⇒ Object



54
55
56
# File 'lib/anycable/rack/socket.rb', line 54

def onopen(&block)
  @_open_handlers << block
end

#requestObject



50
51
52
# File 'lib/anycable/rack/socket.rb', line 50

def request
  @request ||= ::Rack::Request.new(@env)
end

#transmit(data, type: nil) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/anycable/rack/socket.rb', line 36

def transmit(data, type: nil)
  # p "DATA: #{data.class} — #{data.to_s}"
  type ||= data.is_a?(BinaryFrame) ? :binary : :text
  frame = WebSocket::Frame::Outgoing::Server.new(
    version: version,
    data: data,
    type: type
  )
  socket.write(frame.to_s)
rescue Exception => e # rubocop:disable Lint/RescueException
  log(:error, "Socket send failed: #{e}")
  close
end