Class: Tamashii::Server::Connection::ClientSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/tamashii/server/connection/client_socket.rb

Overview

:nodoc: rubocop:disable Metrics/ClassLength

Constant Summary collapse

CONNECTING =
0
OPEN =
1
CLOSING =
2
CLOSED =
3

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server, conn, env, event_loop) ⇒ ClientSocket

TODO: Support define protocols



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/tamashii/server/connection/client_socket.rb', line 33

def initialize(server, conn, env, event_loop)
  @server = server
  @conn = conn
  @env = env
  @event_loop = event_loop

  @id ||= env['REMOTE_ADDR']
  @state = CONNECTING

  @url = ClientSocket.determine_url(@env)
  @driver = setup_driver

  @server.pubsub.subscribe
  @stream = Stream.new(@event_loop, self)
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



29
30
31
# File 'lib/tamashii/server/connection/client_socket.rb', line 29

def env
  @env
end

#idObject

Returns the value of attribute id.



30
31
32
# File 'lib/tamashii/server/connection/client_socket.rb', line 30

def id
  @id
end

#urlObject (readonly)

Returns the value of attribute url.



29
30
31
# File 'lib/tamashii/server/connection/client_socket.rb', line 29

def url
  @url
end

Class Method Details

.determine_url(env) ⇒ Object



9
10
11
12
# File 'lib/tamashii/server/connection/client_socket.rb', line 9

def self.determine_url(env)
  scheme = secure_request?(env) ? 'wss:' : 'ws:'
  "#{scheme}//#{env['HTTP_HOST']}#{env['REQUEST_URI']}"
end

.secure_request?(env) ⇒ Boolean

Returns:

  • (Boolean)


14
15
16
17
18
19
20
21
22
# File 'lib/tamashii/server/connection/client_socket.rb', line 14

def self.secure_request?(env)
  return true if env['HTTPS'] == 'on'
  return true if env['HTTP_X_FORWARDED_SSL'] == 'on'
  return true if env['HTTP_X_FORWARDED_SCHEME'] == 'https'
  return true if env['HTTP_X_FORWARDED_PROTO'] == 'https'
  return true if env['rack.url_scheme'] == 'https'

  false
end

Instance Method Details

#client_goneObject



94
95
96
# File 'lib/tamashii/server/connection/client_socket.rb', line 94

def client_gone
  finialize_close
end

#closeObject



85
86
87
88
# File 'lib/tamashii/server/connection/client_socket.rb', line 85

def close
  # TODO: Define close reason / code
  @driver.close('', 1000)
end

#parse(data) ⇒ Object



90
91
92
# File 'lib/tamashii/server/connection/client_socket.rb', line 90

def parse(data)
  @driver.parse(data)
end

#ping(data, &block) ⇒ Object



81
82
83
# File 'lib/tamashii/server/connection/client_socket.rb', line 81

def ping(data, &block)
  @driver.ping(data, &block)
end

#protocolObject



98
99
100
# File 'lib/tamashii/server/connection/client_socket.rb', line 98

def protocol
  @driver.protocol
end

#rack_responseObject



59
60
61
62
63
# File 'lib/tamashii/server/connection/client_socket.rb', line 59

def rack_response
  start_driver
  Server.logger.info("Accept new websocket connection from #{env['REMOTE_ADDR']}")
  Server::Response.new(message: 'WebSocket Connected')
end

#start_driverObject



49
50
51
52
53
54
55
56
57
# File 'lib/tamashii/server/connection/client_socket.rb', line 49

def start_driver
  return if @driver.nil?
  @stream.hijack_rack_socket

  callback = @env['async.callback']
  callback&.call([101, {}, @stream])

  @driver.start
end

#transmit(message) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/tamashii/server/connection/client_socket.rb', line 71

def transmit(message)
  Server.logger.debug("Send to #{id} with data #{message}")
  case message
  when Numeric then @driver.text(message.to_s)
  when String then @driver.text(message)
  else
    @driver.binary(message)
  end
end

#write(data) ⇒ Object



65
66
67
68
69
# File 'lib/tamashii/server/connection/client_socket.rb', line 65

def write(data)
  @stream.write(data)
rescue => e
  emit_error e.message
end