forked from websocket-rails/websocket-rails
-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathconnection.rb
147 lines (113 loc) · 3.31 KB
/
connection.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
require "uuidtools"
module WebsocketRails
class Connection
include Logging
def self.websocket?(env)
Faye::WebSocket.websocket?(env)
end
attr_reader :id, :dispatcher, :queue, :env, :request, :data_store,
:websocket, :message_handler
delegate :supported_protocols, to: WebsocketRails
delegate :on_open, :on_message, :on_close, :on_error, to: :message_handler
def initialize(request, dispatcher)
@id = UUIDTools::UUID.random_create
@env = request.env.dup
@request = request
@dispatcher = dispatcher
@connected = true
@websocket = Faye::WebSocket.new(request.env, supported_protocols, ping: 10)
@data_store = DataStore::Connection.new(self)
@delegate = WebsocketRails::DelegationController.new
@delegate.instance_variable_set(:@_env, request.env)
@delegate.instance_variable_set(:@_request, request)
bind_message_handler
rescue => ex
raise InvalidConnectionError, ex.message
end
def protocol
@websocket.protocol
end
def enqueue(event)
@queue << event
end
def trigger(event)
send event.serialize
end
def flush
message = []
@queue.flush do |event|
message << event.as_json
end
send message.to_json
end
def send_message(*args)
@message_handler.send_message(*args)
end
def send(message)
@websocket.send message
end
def close!
@websocket.close
end
def close_connection
@data_store.destroy!
dispatcher.connection_manager.close_connection self
end
def rack_response
[ -1, {}, [] ]
end
def controller_delegate
@delegate
end
def connected?
true & @connected
end
def inspect
"#<Connection::#{id}>"
end
def to_s
inspect
end
def user_connection?
not user_identifier.nil?
end
def user
return unless user_connection?
controller_delegate.current_user
end
def user_identifier
@user_identifier ||= begin
identifier = WebsocketRails.config.user_identifier
return unless current_user_responds_to?(identifier)
controller_delegate.current_user.send(identifier)
end
end
def register_user
dispatcher.connection_manager.register_user_connection self
end
def destroy_user
dispatcher.connection_manager.destroy_user_connection self
end
private
def dispatch(event)
dispatcher.dispatch event
end
def connection_manager
dispatcher.connection_manager
end
def current_user_responds_to?(identifier)
controller_delegate &&
controller_delegate.respond_to?(:current_user) &&
controller_delegate.current_user &&
controller_delegate.current_user.respond_to?(identifier)
end
def bind_message_handler
handler_class = AbstractMessageHandler.handler_for_protocol(websocket.protocol)
@message_handler = handler_class.new(self)
@websocket.onopen = @message_handler.method(:on_open)
@websocket.onmessage = @message_handler.method(:on_message)
@websocket.onclose = @message_handler.method(:on_close)
@websocket.onerror = @message_handler.method(:on_error)
end
end
end