class Citrus::Common::Service::SessionService

SessionService

Constants

EXPORTED_SESSION_FIELDS
FRONTEND_SESSION_FIELDS

Attributes

sessions[R]

Public Class Methods

new(args={}) click to toggle source

Initialize the service

@param [Hash] args

# File lib/citrus/common/service/session_service.rb, line 29
def initialize args={}
  @single_session = args[:single_session] || false
  @sessions = {}
  @uid_map = {}
end

Public Instance Methods

bind(sid, user_id) { |exception 'session does not exist, sid: ' + sid| ... } click to toggle source

Bind the session with a user id

@param [Integer] sid @param [String] user_id

# 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) click to toggle source

Create a new session

@param [Integer] sid @param [String] frontend_id @param [Object] socket

# 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) click to toggle source

Get session by id

@param [Integer] sid

# File lib/citrus/common/service/session_service.rb, line 139
def get sid
  @sessions[sid]
end
get_by_uid(uid) click to toggle source

Get sessions by user id

@param [String] uid

# 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) click to toggle source

Get client remote address by session id

@param [Integer] sid

# 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) { |'session does not exist, sid: ' + sid| ... } click to toggle source

Import the key/value into session

@param [Integer] sid @param [String] key @param [Hash] value

# 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) { |'session does not exist, sid: ' + sid| ... } click to toggle source

Import new value for the existed session

@param [Integer] sid @param [Hash] settings

# 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='') { || ... } click to toggle source

Kick all the sessions offline under the user id

@param [String] uid @param [String] reason

# 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) { || ... } click to toggle source

Kick a user offline by session id

@param [Integer] sid

# 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) click to toggle source

Remove session by session id

@param [Integer] sid

# 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) click to toggle source

Send message to the client by session id

@param [Integer] sid @param [Hash] msg

# 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) click to toggle source

Send message to the client by user id

@param [String] uid @param [Hash] msg

# 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) { |exception 'session does not exist, sid: ' + sid| ... } click to toggle source

Unbind a session with the user id

@param [Integer] sid @param [String] uid

# 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

Private Instance Methods

send(session, msg) click to toggle source

Send message to the client that associated with the session

@param [Object] session @param [Hash] msg

@private

# File lib/citrus/common/service/session_service.rb, line 270
def send session, msg
  session.send msg; true
end