pomelo-citrus 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +20 -0
- data/Rakefile +0 -0
- data/citrus.gemspec +35 -0
- data/lib/citrus.rb +18 -0
- data/lib/citrus/application.rb +237 -0
- data/lib/citrus/citrus.rb +27 -0
- data/lib/citrus/common/remote/backend/msg_remote.rb +57 -0
- data/lib/citrus/common/remote/frontend/channel_remote.rb +73 -0
- data/lib/citrus/common/remote/frontend/session_remote.rb +108 -0
- data/lib/citrus/common/service/backend_session_service.rb +265 -0
- data/lib/citrus/common/service/channel_service.rb +485 -0
- data/lib/citrus/common/service/connection_service.rb +71 -0
- data/lib/citrus/common/service/filter_service.rb +92 -0
- data/lib/citrus/common/service/handler_service.rb +63 -0
- data/lib/citrus/common/service/session_service.rb +446 -0
- data/lib/citrus/components/backend_session.rb +32 -0
- data/lib/citrus/components/channel.rb +33 -0
- data/lib/citrus/components/component.rb +19 -0
- data/lib/citrus/components/connection.rb +48 -0
- data/lib/citrus/components/connector.rb +265 -0
- data/lib/citrus/components/master.rb +40 -0
- data/lib/citrus/components/monitor.rb +48 -0
- data/lib/citrus/components/proxy.rb +195 -0
- data/lib/citrus/components/push_scheduler.rb +74 -0
- data/lib/citrus/components/remote.rb +71 -0
- data/lib/citrus/components/server.rb +61 -0
- data/lib/citrus/components/session.rb +41 -0
- data/lib/citrus/connectors/commands/handshake.rb +22 -0
- data/lib/citrus/connectors/commands/heartbeat.rb +22 -0
- data/lib/citrus/connectors/commands/kick.rb +22 -0
- data/lib/citrus/connectors/common/coder.rb +21 -0
- data/lib/citrus/connectors/common/handler.rb +21 -0
- data/lib/citrus/connectors/ws_connector.rb +110 -0
- data/lib/citrus/connectors/ws_socket.rb +75 -0
- data/lib/citrus/filters/handler/handler_filter.rb +19 -0
- data/lib/citrus/filters/handler/too_busy.rb +16 -0
- data/lib/citrus/filters/rpc/rpc_filter.rb +19 -0
- data/lib/citrus/filters/rpc/too_busy.rb +16 -0
- data/lib/citrus/master/master.rb +60 -0
- data/lib/citrus/master/starter.rb +73 -0
- data/lib/citrus/master/watchdog.rb +83 -0
- data/lib/citrus/modules/console.rb +45 -0
- data/lib/citrus/modules/console_module.rb +35 -0
- data/lib/citrus/modules/master_watcher.rb +88 -0
- data/lib/citrus/modules/monitor_watcher.rb +86 -0
- data/lib/citrus/monitor/monitor.rb +61 -0
- data/lib/citrus/push_schedulers/buffer.rb +16 -0
- data/lib/citrus/push_schedulers/direct.rb +76 -0
- data/lib/citrus/server/server.rb +327 -0
- data/lib/citrus/util/app_util.rb +203 -0
- data/lib/citrus/util/constants.rb +19 -0
- data/lib/citrus/util/countdown_latch.rb +42 -0
- data/lib/citrus/util/events.rb +14 -0
- data/lib/citrus/util/module_util.rb +68 -0
- data/lib/citrus/util/path_util.rb +50 -0
- data/lib/citrus/util/utils.rb +49 -0
- data/lib/citrus/version.rb +7 -0
- metadata +241 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 25 July 2014
|
4
|
+
|
5
|
+
module Citrus
|
6
|
+
# Common
|
7
|
+
#
|
8
|
+
#
|
9
|
+
module Common
|
10
|
+
# Service
|
11
|
+
#
|
12
|
+
#
|
13
|
+
module Service
|
14
|
+
# ConnectionService
|
15
|
+
#
|
16
|
+
#
|
17
|
+
class ConnectionService
|
18
|
+
# Initialize the service
|
19
|
+
#
|
20
|
+
# @param [Object] app
|
21
|
+
def initialize app
|
22
|
+
@server_id = app.server_id
|
23
|
+
@conn_count = 0
|
24
|
+
@logined_count = 0
|
25
|
+
@logined = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add logined user
|
29
|
+
#
|
30
|
+
# @param [String] uid
|
31
|
+
# @param [Hash] info
|
32
|
+
def add_logined_user uid, info={}
|
33
|
+
@logined_count += 1 unless @logined[uid]
|
34
|
+
info[:uid] = uid
|
35
|
+
@logined[uid] = info
|
36
|
+
end
|
37
|
+
|
38
|
+
# Increase connection count
|
39
|
+
def increase_conn_count
|
40
|
+
@conn_count += 1
|
41
|
+
end
|
42
|
+
|
43
|
+
# Remove logined user
|
44
|
+
#
|
45
|
+
# @param [String] uid
|
46
|
+
def remove_logined_user uid
|
47
|
+
@logined_count -= 1 if @logined[uid]
|
48
|
+
@logined.delete uid
|
49
|
+
end
|
50
|
+
|
51
|
+
# Decrease connection count
|
52
|
+
#
|
53
|
+
# @param [String] uid
|
54
|
+
def decrease_conn_count uid
|
55
|
+
@conn_count -= 1 if @conn_count > 0
|
56
|
+
remove_logined_user uid unless uid.empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get statistics info
|
60
|
+
def get_statistics_info
|
61
|
+
{
|
62
|
+
:server_id => @server_id,
|
63
|
+
:conn_count => @conn_count,
|
64
|
+
:logined_count => @logined_count,
|
65
|
+
:logined_list => @logined.values
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 29 July 2014
|
4
|
+
|
5
|
+
module Citrus
|
6
|
+
# Common
|
7
|
+
#
|
8
|
+
#
|
9
|
+
module Common
|
10
|
+
# Service
|
11
|
+
#
|
12
|
+
#
|
13
|
+
module Service
|
14
|
+
# FilterService
|
15
|
+
#
|
16
|
+
#
|
17
|
+
class FilterService
|
18
|
+
# Initialize the service
|
19
|
+
def initialize
|
20
|
+
@befores = []
|
21
|
+
@afters = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add before filter into the filter chain
|
25
|
+
#
|
26
|
+
# @param [#call] filter
|
27
|
+
def before filter
|
28
|
+
@befores << filter
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add after filter into the filter chain
|
32
|
+
#
|
33
|
+
# @param [#call] filter
|
34
|
+
def after filter
|
35
|
+
@afters.unshift filter
|
36
|
+
end
|
37
|
+
|
38
|
+
# Do the before filter chain
|
39
|
+
#
|
40
|
+
# @param [Hash] msg
|
41
|
+
# @param [Object] session
|
42
|
+
def before_filter msg, session, &block
|
43
|
+
index = 0
|
44
|
+
|
45
|
+
next_p = Proc.new { |err, resp, args|
|
46
|
+
if err || index >= @befores.length
|
47
|
+
block_given? and yield err, resp, args
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
handler = @befores[index]
|
52
|
+
index += 1
|
53
|
+
|
54
|
+
if handler.respond_to? :call
|
55
|
+
handler.call msg, session, &next_p
|
56
|
+
else
|
57
|
+
next_p.call Exception.new 'invalid before filter'
|
58
|
+
end
|
59
|
+
}
|
60
|
+
next_p.call
|
61
|
+
end
|
62
|
+
|
63
|
+
# Do the after filter chain
|
64
|
+
#
|
65
|
+
# @param [Object] err
|
66
|
+
# @param [Hash] msg
|
67
|
+
# @param [Object] session
|
68
|
+
# @param [Hash] resp
|
69
|
+
def after_filter err, msg, session, resp, &block
|
70
|
+
index = 0
|
71
|
+
|
72
|
+
next_p = Proc.new { |err|
|
73
|
+
if index >= @afters.length
|
74
|
+
block_given? and yield err
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
handler = @afters[index]
|
79
|
+
index += 1
|
80
|
+
|
81
|
+
if handler.respond_to? :call
|
82
|
+
handler.call err, msg, session, resp, &next_p
|
83
|
+
else
|
84
|
+
next_p.call Exception.new 'invalid after filter'
|
85
|
+
end
|
86
|
+
}
|
87
|
+
next_p.call err
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 29 July 2014
|
4
|
+
|
5
|
+
module Citrus
|
6
|
+
# Common
|
7
|
+
#
|
8
|
+
#
|
9
|
+
module Common
|
10
|
+
# Service
|
11
|
+
#
|
12
|
+
#
|
13
|
+
module Service
|
14
|
+
# HandlerService
|
15
|
+
#
|
16
|
+
#
|
17
|
+
class HandlerService
|
18
|
+
# Initialize the service
|
19
|
+
#
|
20
|
+
# @param [Object] app
|
21
|
+
# @param [Hash] handlers
|
22
|
+
def initialize app, handlers={}
|
23
|
+
@app = app
|
24
|
+
@handlers = handlers
|
25
|
+
end
|
26
|
+
|
27
|
+
# Handle message from the client
|
28
|
+
#
|
29
|
+
# @param [Hash] route_record
|
30
|
+
# @param [Hash] msg
|
31
|
+
# @param [Object] session
|
32
|
+
def handle route_record, msg, session, &block
|
33
|
+
handler = get_handler route_record
|
34
|
+
unless handler
|
35
|
+
block_given? and yield Exception.new 'failed to find the handler'
|
36
|
+
return
|
37
|
+
end
|
38
|
+
handler.send(route_record['method'], msg, session) { |err, resp, args|
|
39
|
+
block_given? and yield err, resp, args
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Get handler by route record
|
46
|
+
#
|
47
|
+
# @param [Hash] route_record
|
48
|
+
#
|
49
|
+
# @private
|
50
|
+
def get_handler route_record
|
51
|
+
handler = @handlers[route_record['handler']]
|
52
|
+
unless handler
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
unless handler.respond_to? route_record['method']
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
handler
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,446 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 19 July 2014
|
4
|
+
|
5
|
+
module Citrus
|
6
|
+
# Common
|
7
|
+
#
|
8
|
+
#
|
9
|
+
module Common
|
10
|
+
# Service
|
11
|
+
#
|
12
|
+
#
|
13
|
+
module Service
|
14
|
+
# SessionService
|
15
|
+
#
|
16
|
+
#
|
17
|
+
class SessionService
|
18
|
+
#
|
19
|
+
#
|
20
|
+
#
|
21
|
+
FRONTEND_SESSION_FIELDS = ['id', 'frontend_id', 'uid', 'session_service']
|
22
|
+
EXPORTED_SESSION_FIELDS = ['id', 'frontend_id', 'uid', 'settings']
|
23
|
+
|
24
|
+
attr_reader :sessions
|
25
|
+
|
26
|
+
# Initialize the service
|
27
|
+
#
|
28
|
+
# @param [Hash] args
|
29
|
+
def initialize args={}
|
30
|
+
@single_session = args[:single_session] || false
|
31
|
+
@sessions = {}
|
32
|
+
@uid_map = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Create a new session
|
36
|
+
#
|
37
|
+
# @param [Integer] sid
|
38
|
+
# @param [String] frontend_id
|
39
|
+
# @param [Object] socket
|
40
|
+
def create sid, frontend_id, socket
|
41
|
+
session = Session.new sid, frontend_id, socket, self
|
42
|
+
@sessions[session.id] = session
|
43
|
+
session
|
44
|
+
end
|
45
|
+
|
46
|
+
# Bind the session with a user id
|
47
|
+
#
|
48
|
+
# @param [Integer] sid
|
49
|
+
# @param [String] user_id
|
50
|
+
def bind sid, user_id, &block
|
51
|
+
session = @sessions[sid]
|
52
|
+
unless session
|
53
|
+
EM.next_tick {
|
54
|
+
block_given? and yield Exception.new 'session does not exist, sid: ' + sid
|
55
|
+
}
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
if session.uid
|
60
|
+
if session.uid == uid
|
61
|
+
# already bound with the same uid
|
62
|
+
block_given? and yield
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
# already bound with another uid
|
67
|
+
EM.next_tick {
|
68
|
+
block_given? and yield Exception.new 'session has already bound with ' + session.uid
|
69
|
+
}
|
70
|
+
return
|
71
|
+
end
|
72
|
+
|
73
|
+
sessions = @uid_map[uid]
|
74
|
+
|
75
|
+
if sessions && @single_session
|
76
|
+
EM.next_tick {
|
77
|
+
block_given? and yield Exception.new 'single_session is enabled and session has already bound with uid: ' + uid
|
78
|
+
}
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
sessions = @uid_map[uid] = [] unless sessions
|
83
|
+
|
84
|
+
sessions.each { |s|
|
85
|
+
# session has binded with the uid
|
86
|
+
if s.id == session.id
|
87
|
+
EM.next_tick { block_given? and yield }
|
88
|
+
return
|
89
|
+
end
|
90
|
+
}
|
91
|
+
sessions << session
|
92
|
+
|
93
|
+
session.bind uid
|
94
|
+
|
95
|
+
EM.next_tick { yield } if block_given?
|
96
|
+
end
|
97
|
+
|
98
|
+
# Unbind a session with the user id
|
99
|
+
#
|
100
|
+
# @param [Integer] sid
|
101
|
+
# @param [String] uid
|
102
|
+
def unbind sid, uid, &block
|
103
|
+
session = @sessions[sid]
|
104
|
+
unless session
|
105
|
+
EM.next_tick {
|
106
|
+
block_given? and yield Exception.new 'session does not exist, sid: ' + sid
|
107
|
+
}
|
108
|
+
return
|
109
|
+
end
|
110
|
+
|
111
|
+
unless session.uid && session.uid == uid
|
112
|
+
EM.next_tick {
|
113
|
+
block_given? and yield Exception.new 'session has not bind with ' + uid
|
114
|
+
}
|
115
|
+
return
|
116
|
+
end
|
117
|
+
|
118
|
+
sessions = @uid_map[uid]
|
119
|
+
if sessions
|
120
|
+
sessions.each { |s|
|
121
|
+
if s.id == sid
|
122
|
+
sessions.delete s
|
123
|
+
break
|
124
|
+
end
|
125
|
+
}
|
126
|
+
|
127
|
+
if sessions.length == 0
|
128
|
+
@uid_map.delete uid
|
129
|
+
end
|
130
|
+
end
|
131
|
+
session.unbind uid
|
132
|
+
|
133
|
+
EM.next_tick { yield } if block_given?
|
134
|
+
end
|
135
|
+
|
136
|
+
# Get session by id
|
137
|
+
#
|
138
|
+
# @param [Integer] sid
|
139
|
+
def get sid
|
140
|
+
@sessions[sid]
|
141
|
+
end
|
142
|
+
|
143
|
+
# Get sessions by user id
|
144
|
+
#
|
145
|
+
# @param [String] uid
|
146
|
+
def get_by_uid uid
|
147
|
+
@uid_map[uid]
|
148
|
+
end
|
149
|
+
|
150
|
+
# Remove session by session id
|
151
|
+
#
|
152
|
+
# @param [Integer] sid
|
153
|
+
def remove sid
|
154
|
+
if session = @sessions[sid]
|
155
|
+
uid = session.uid
|
156
|
+
@sessions.delete session.id
|
157
|
+
|
158
|
+
sessions = @uid_map[uid]
|
159
|
+
return unless sessions
|
160
|
+
|
161
|
+
sessions.each { |s|
|
162
|
+
if s.id == sid
|
163
|
+
sessions.delete s
|
164
|
+
@uid_map.delete uid if sessions.length == 0
|
165
|
+
end
|
166
|
+
}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Import the key/value into session
|
171
|
+
#
|
172
|
+
# @param [Integer] sid
|
173
|
+
# @param [String] key
|
174
|
+
# @param [Hash] value
|
175
|
+
def import sid, key, value, &block
|
176
|
+
session = @sessions[sid]
|
177
|
+
unless session
|
178
|
+
block_given? and yield 'session does not exist, sid: ' + sid
|
179
|
+
return
|
180
|
+
end
|
181
|
+
session.set key, value
|
182
|
+
block_given? and yield
|
183
|
+
end
|
184
|
+
|
185
|
+
# Import new value for the existed session
|
186
|
+
#
|
187
|
+
# @param [Integer] sid
|
188
|
+
# @param [Hash] settings
|
189
|
+
def import_all sid, settings, &block
|
190
|
+
session = @sessions[sid]
|
191
|
+
unless session
|
192
|
+
block_given? and yield 'session does not exist, sid: ' + sid
|
193
|
+
return
|
194
|
+
end
|
195
|
+
|
196
|
+
settings.each_pair { |key, value| session.set key, value }
|
197
|
+
block_given? and yield
|
198
|
+
end
|
199
|
+
|
200
|
+
# Kick all the sessions offline under the user id
|
201
|
+
#
|
202
|
+
# @param [String] uid
|
203
|
+
# @param [String] reason
|
204
|
+
def kick uid, reason='', &block
|
205
|
+
if sessions = get_by_uid(uid)
|
206
|
+
# notify client
|
207
|
+
sids = []
|
208
|
+
sessions.each { |session| sids << session.id }
|
209
|
+
sids.each { |sid| @sessions[sid].closed reason }
|
210
|
+
end
|
211
|
+
EM.next_tick { block_given? and yield }
|
212
|
+
end
|
213
|
+
|
214
|
+
# Kick a user offline by session id
|
215
|
+
#
|
216
|
+
# @param [Integer] sid
|
217
|
+
def kick_by_session_id sid, &block
|
218
|
+
session = get sid
|
219
|
+
session.closed 'kick' if session
|
220
|
+
EM.next_tick { block_given? and yield }
|
221
|
+
end
|
222
|
+
|
223
|
+
# Get client remote address by session id
|
224
|
+
#
|
225
|
+
# @param [Integer] sid
|
226
|
+
def get_client_address_by_session_id sid
|
227
|
+
session = get sid
|
228
|
+
return session.socket.remote_addres if session
|
229
|
+
return nil
|
230
|
+
end
|
231
|
+
|
232
|
+
# Send message to the client by session id
|
233
|
+
#
|
234
|
+
# @param [Integer] sid
|
235
|
+
# @param [Hash] msg
|
236
|
+
def send_message sid, msg
|
237
|
+
session = @sessions[sid]
|
238
|
+
|
239
|
+
unless session
|
240
|
+
return false
|
241
|
+
end
|
242
|
+
|
243
|
+
send session, msg
|
244
|
+
end
|
245
|
+
|
246
|
+
# Send message to the client by user id
|
247
|
+
#
|
248
|
+
# @param [String] uid
|
249
|
+
# @param [Hash] msg
|
250
|
+
def send_message_by_uid uid, msg
|
251
|
+
sessions = @uid_map[uid]
|
252
|
+
|
253
|
+
unless sessions
|
254
|
+
return false
|
255
|
+
end
|
256
|
+
|
257
|
+
sessions.each { |session|
|
258
|
+
send session, msg
|
259
|
+
}
|
260
|
+
end
|
261
|
+
|
262
|
+
private
|
263
|
+
|
264
|
+
# Send message to the client that associated with the session
|
265
|
+
#
|
266
|
+
# @param [Object] session
|
267
|
+
# @param [Hash] msg
|
268
|
+
#
|
269
|
+
# @private
|
270
|
+
def send session, msg
|
271
|
+
session.send msg; true
|
272
|
+
end
|
273
|
+
|
274
|
+
# Session
|
275
|
+
#
|
276
|
+
#
|
277
|
+
class Session
|
278
|
+
include Utils::EventEmitter
|
279
|
+
|
280
|
+
attr_reader :id, :frontend_id, :uid, :settings, :session_service
|
281
|
+
|
282
|
+
# Create a new session
|
283
|
+
#
|
284
|
+
# @param [Integer] sid
|
285
|
+
# @param [String] frontend_id
|
286
|
+
# @param [Object] socket
|
287
|
+
# @param [Object] service
|
288
|
+
def initialize sid, frontend_id, socket, service
|
289
|
+
@id = sid
|
290
|
+
@frontend_id = frontend_id
|
291
|
+
@uid = nil
|
292
|
+
@settings = {}
|
293
|
+
|
294
|
+
@socket = socket
|
295
|
+
@session_service = service
|
296
|
+
@state = :state_inited
|
297
|
+
end
|
298
|
+
|
299
|
+
# Export current session as frontend session
|
300
|
+
def to_frontend_session
|
301
|
+
FrontendSession.new self
|
302
|
+
end
|
303
|
+
|
304
|
+
# Bind the session with the uid
|
305
|
+
#
|
306
|
+
# @param [String] uid
|
307
|
+
def bind uid
|
308
|
+
@uid = uid
|
309
|
+
emit :bind, uid
|
310
|
+
end
|
311
|
+
|
312
|
+
# Unbind the session with the uid
|
313
|
+
#
|
314
|
+
# @param [String] uid
|
315
|
+
def unbind uid
|
316
|
+
@uid = nil
|
317
|
+
emit :unbind, uid
|
318
|
+
end
|
319
|
+
|
320
|
+
# Set value for the session
|
321
|
+
#
|
322
|
+
# @param [String] key
|
323
|
+
# @param [Hash] value
|
324
|
+
def set key, value
|
325
|
+
@settings[key] = value
|
326
|
+
end
|
327
|
+
|
328
|
+
# Get value from the session
|
329
|
+
#
|
330
|
+
# @param [String] key
|
331
|
+
def get key
|
332
|
+
@settings[key]
|
333
|
+
end
|
334
|
+
|
335
|
+
# Send message to the session
|
336
|
+
#
|
337
|
+
# @param [Hash] msg
|
338
|
+
def send msg
|
339
|
+
@socket.send msg
|
340
|
+
end
|
341
|
+
|
342
|
+
# Send message to the session in batch
|
343
|
+
#
|
344
|
+
# @param [Array] msgs
|
345
|
+
def send_batch msgs
|
346
|
+
@socket.send_batch msgs
|
347
|
+
end
|
348
|
+
|
349
|
+
# Closed callback for the session which would disconnect client in next tick
|
350
|
+
#
|
351
|
+
# @param [String] reason
|
352
|
+
def closed reason=''
|
353
|
+
return if @state == :state_closed
|
354
|
+
|
355
|
+
@state = :state_closed
|
356
|
+
@service.remove @id
|
357
|
+
|
358
|
+
emit :closed, to_frontend_session, reason
|
359
|
+
@socket.emit :closing, reason
|
360
|
+
|
361
|
+
EM.next_tick { @socket.disconnect }
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# FrontendSession
|
366
|
+
#
|
367
|
+
#
|
368
|
+
class FrontendSession
|
369
|
+
include Utils::EventEmitter
|
370
|
+
|
371
|
+
# Create a new frontend session
|
372
|
+
#
|
373
|
+
# @param [Object] session
|
374
|
+
def initialize session
|
375
|
+
FRONTEND_SESSION_FIELDS.each { |field|
|
376
|
+
instance_eval %Q{ @#{field} = session.#{field} }
|
377
|
+
}
|
378
|
+
# deep copy for settings
|
379
|
+
@settings = session.settings.dup
|
380
|
+
@session = session
|
381
|
+
end
|
382
|
+
|
383
|
+
# Bind the frontend session with the uid
|
384
|
+
#
|
385
|
+
# @param [String] uid
|
386
|
+
def bind uid, &block
|
387
|
+
@session_service.bind(@id, uid) { |err|
|
388
|
+
unless err
|
389
|
+
@uid = uid
|
390
|
+
end
|
391
|
+
block_given? and yield err
|
392
|
+
}
|
393
|
+
end
|
394
|
+
|
395
|
+
# Unbind the session with the uid
|
396
|
+
#
|
397
|
+
# @param [String] uid
|
398
|
+
def unbind uid, &block
|
399
|
+
@session_service.unbind(@id, uid) { |err|
|
400
|
+
unless err
|
401
|
+
@uid = nil
|
402
|
+
end
|
403
|
+
block_given? and yield err
|
404
|
+
}
|
405
|
+
end
|
406
|
+
|
407
|
+
# Set value for the frontend session
|
408
|
+
#
|
409
|
+
# @param [String] key
|
410
|
+
# @param [Hash] value
|
411
|
+
def set key, value
|
412
|
+
@settings[key] = value
|
413
|
+
end
|
414
|
+
|
415
|
+
# Get value from the frontend session
|
416
|
+
#
|
417
|
+
# @param [String] key
|
418
|
+
def get key
|
419
|
+
@settings[key]
|
420
|
+
end
|
421
|
+
|
422
|
+
# Push value to the internal session
|
423
|
+
#
|
424
|
+
# @param [String] key
|
425
|
+
def push key, &block
|
426
|
+
@session_service.import @id, key, get(key), &block
|
427
|
+
end
|
428
|
+
|
429
|
+
# Push all the key/value pairs to the internal session
|
430
|
+
def push_all &block
|
431
|
+
@session_service.import_all @id, @settings, &block
|
432
|
+
end
|
433
|
+
|
434
|
+
# Export the key/values for serialization
|
435
|
+
def export
|
436
|
+
res = {}
|
437
|
+
EXPORTED_SESSION_FIELDS.each { |field|
|
438
|
+
instance_eval %Q{ res['#{field}'] = @#{field} }
|
439
|
+
}
|
440
|
+
res
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|