Class: Citrus::Common::Service::SessionService

Inherits:
Object
  • Object
show all
Defined in:
lib/citrus/common/service/session_service.rb

Overview

SessionService

Defined Under Namespace

Classes: FrontendSession, Session

Constant Summary collapse

FRONTEND_SESSION_FIELDS =
['id', 'frontend_id', 'uid', 'session_service']
EXPORTED_SESSION_FIELDS =
['id', 'frontend_id', 'uid', 'settings']

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ SessionService

Initialize the service

Parameters:

  • args (Hash) (defaults to: {})


29
30
31
32
33
# File 'lib/citrus/common/service/session_service.rb', line 29

def initialize args={}
  @single_session = args[:single_session] || false
  @sessions = {}
  @uid_map = {}
end

Instance Attribute Details

#sessionsObject (readonly)

Returns the value of attribute sessions.



24
25
26
# File 'lib/citrus/common/service/session_service.rb', line 24

def sessions
  @sessions
end

Instance Method Details

#bind(sid, user_id, &block) ⇒ Object

Bind the session with a user id

Parameters:

  • sid (Integer)
  • user_id (String)


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
# File 'lib/citrus/common/service/session_service.rb', line 50

def bind sid, user_id, &block
  session = @sessions[sid]
  unless session
    EM.next_tick {
      block_given? and yield Exception.new 'session does not exist, sid: ' + sid
    }
    return
  end

  if session.uid
    if session.uid == uid
      # already bound with the same uid
      block_given? and yield
      return
    end

    # already bound with another uid
    EM.next_tick {
      block_given? and yield Exception.new 'session has already bound with ' + session.uid
    }
    return
  end

  sessions = @uid_map[uid]

  if sessions && @single_session
    EM.next_tick {
      block_given? and yield Exception.new 'single_session is enabled and session has already bound with uid: ' + uid
    }
    return
  end

  sessions = @uid_map[uid] = [] unless sessions

  sessions.each { |s|
    # session has binded with the uid
    if s.id == session.id
      EM.next_tick { block_given? and yield }
      return
    end
  }
  sessions << session

  session.bind uid

  EM.next_tick { yield } if block_given?
end

#create(sid, frontend_id, socket) ⇒ Object

Create a new session

Parameters:

  • sid (Integer)
  • frontend_id (String)
  • socket (Object)


40
41
42
43
44
# File 'lib/citrus/common/service/session_service.rb', line 40

def create sid, frontend_id, socket
  session = Session.new sid, frontend_id, socket, self
  @sessions[session.id] = session
  session
end

#get(sid) ⇒ Object

Get session by id

Parameters:

  • sid (Integer)


139
140
141
# File 'lib/citrus/common/service/session_service.rb', line 139

def get sid
  @sessions[sid]
end

#get_by_uid(uid) ⇒ Object

Get sessions by user id

Parameters:

  • uid (String)


146
147
148
# File 'lib/citrus/common/service/session_service.rb', line 146

def get_by_uid uid
  @uid_map[uid]
end

#get_client_address_by_session_id(sid) ⇒ Object

Get client remote address by session id

Parameters:

  • sid (Integer)


226
227
228
229
230
# File 'lib/citrus/common/service/session_service.rb', line 226

def get_client_address_by_session_id sid
  session = get sid
  return session.socket.remote_addres if session
  return nil
end

#import(sid, key, value, &block) ⇒ Object

Import the key/value into session

Parameters:

  • sid (Integer)
  • key (String)
  • value (Hash)


175
176
177
178
179
180
181
182
183
# File 'lib/citrus/common/service/session_service.rb', line 175

def import sid, key, value, &block
  session = @sessions[sid]
  unless session
    block_given? and yield 'session does not exist, sid: ' + sid
    return
  end
  session.set key, value
  block_given? and yield
end

#import_all(sid, settings, &block) ⇒ Object

Import new value for the existed session

Parameters:

  • sid (Integer)
  • settings (Hash)


189
190
191
192
193
194
195
196
197
198
# File 'lib/citrus/common/service/session_service.rb', line 189

def import_all sid, settings, &block
  session = @sessions[sid]
  unless session
    block_given? and yield 'session does not exist, sid: ' + sid
    return
  end

  settings.each_pair { |key, value| session.set key, value }
  block_given? and yield
end

#kick(uid, reason = '', &block) ⇒ Object

Kick all the sessions offline under the user id

Parameters:

  • uid (String)
  • reason (String) (defaults to: '')


204
205
206
207
208
209
210
211
212
# File 'lib/citrus/common/service/session_service.rb', line 204

def kick uid, reason='', &block
  if sessions = get_by_uid(uid)
    # notify client
    sids = []
    sessions.each { |session| sids << session.id }
    sids.each { |sid| @sessions[sid].closed reason }
  end
  EM.next_tick { block_given? and yield }
end

#kick_by_session_id(sid, &block) ⇒ Object

Kick a user offline by session id

Parameters:

  • sid (Integer)


217
218
219
220
221
# File 'lib/citrus/common/service/session_service.rb', line 217

def kick_by_session_id sid, &block
  session = get sid
  session.closed 'kick' if session
  EM.next_tick { block_given? and yield }
end

#remove(sid) ⇒ Object

Remove session by session id

Parameters:

  • sid (Integer)


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/citrus/common/service/session_service.rb', line 153

def remove sid
  if session = @sessions[sid]
    uid = session.uid
    @sessions.delete session.id

    sessions = @uid_map[uid]
    return unless sessions

    sessions.each { |s|
      if s.id == sid
        sessions.delete s
        @uid_map.delete uid if sessions.length == 0
      end
    }
  end
end

#send_message(sid, msg) ⇒ Object

Send message to the client by session id

Parameters:

  • sid (Integer)
  • msg (Hash)


236
237
238
239
240
241
242
243
244
# File 'lib/citrus/common/service/session_service.rb', line 236

def send_message sid, msg
  session = @sessions[sid]

  unless session
    return false
  end

  send session, msg
end

#send_message_by_uid(uid, msg) ⇒ Object

Send message to the client by user id

Parameters:

  • uid (String)
  • msg (Hash)


250
251
252
253
254
255
256
257
258
259
260
# File 'lib/citrus/common/service/session_service.rb', line 250

def send_message_by_uid uid, msg
  sessions = @uid_map[uid]

  unless sessions
    return false
  end

  sessions.each { |session|
    send session, msg
  }
end

#unbind(sid, uid, &block) ⇒ Object

Unbind a session with the user id

Parameters:

  • sid (Integer)
  • uid (String)


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
# File 'lib/citrus/common/service/session_service.rb', line 102

def unbind sid, uid, &block
  session = @sessions[sid]
  unless session
    EM.next_tick {
      block_given? and yield Exception.new 'session does not exist, sid: ' + sid
    }
    return
  end

  unless session.uid && session.uid == uid
    EM.next_tick {
      block_given? and yield Exception.new 'session has not bind with ' + uid
    }
    return
  end

  sessions = @uid_map[uid]
  if sessions
    sessions.each { |s|
      if s.id == sid
        sessions.delete s
        break
      end
    }

    if sessions.length == 0
      @uid_map.delete uid
    end
  end
  session.unbind uid

  EM.next_tick { yield } if block_given?
end