|
|
|
|
package session
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"git.noahlan.cn/northlan/nnet/nface"
|
|
|
|
|
"sync"
|
|
|
|
|
"sync/atomic"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var _ nface.ISession = (*Session)(nil)
|
|
|
|
|
|
|
|
|
|
type Session struct {
|
|
|
|
|
sync.RWMutex // 数据锁
|
|
|
|
|
|
|
|
|
|
id int64 // Session全局唯一ID
|
|
|
|
|
uid string // 用户ID,不绑定的情况下与sid一致
|
|
|
|
|
data map[string]interface{} // session数据存储(内存)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func New() nface.ISession {
|
|
|
|
|
return &Session{
|
|
|
|
|
id: sessionIDMgrInstance.SessionID(),
|
|
|
|
|
uid: "",
|
|
|
|
|
data: make(map[string]interface{}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) ID() int64 {
|
|
|
|
|
return s.id
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) UID() string {
|
|
|
|
|
return s.uid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) Bind(uid string) {
|
|
|
|
|
s.uid = uid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) Attribute(key string) interface{} {
|
|
|
|
|
s.RLock()
|
|
|
|
|
defer s.RUnlock()
|
|
|
|
|
|
|
|
|
|
return s.data[key]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) Keys() []string {
|
|
|
|
|
s.RLock()
|
|
|
|
|
defer s.RUnlock()
|
|
|
|
|
|
|
|
|
|
keys := make([]string, 0, len(s.data))
|
|
|
|
|
for k := range s.data {
|
|
|
|
|
keys = append(keys, k)
|
|
|
|
|
}
|
|
|
|
|
return keys
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) Exists(key string) bool {
|
|
|
|
|
s.RLock()
|
|
|
|
|
defer s.RUnlock()
|
|
|
|
|
|
|
|
|
|
_, has := s.data[key]
|
|
|
|
|
return has
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) Attributes() map[string]interface{} {
|
|
|
|
|
s.RLock()
|
|
|
|
|
defer s.RUnlock()
|
|
|
|
|
|
|
|
|
|
return s.data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) RemoveAttribute(key string) {
|
|
|
|
|
s.Lock()
|
|
|
|
|
defer s.Unlock()
|
|
|
|
|
|
|
|
|
|
delete(s.data, key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) SetAttribute(key string, value interface{}) {
|
|
|
|
|
s.Lock()
|
|
|
|
|
defer s.Unlock()
|
|
|
|
|
|
|
|
|
|
s.data[key] = value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Session) Invalidate() {
|
|
|
|
|
s.Lock()
|
|
|
|
|
defer s.Unlock()
|
|
|
|
|
|
|
|
|
|
s.id = 0
|
|
|
|
|
s.uid = ""
|
|
|
|
|
s.data = make(map[string]interface{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var sessionIDMgrInstance = newSessionIDMgr()
|
|
|
|
|
|
|
|
|
|
type sessionIDMgr struct {
|
|
|
|
|
count int64
|
|
|
|
|
sid int64
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newSessionIDMgr() *sessionIDMgr {
|
|
|
|
|
return &sessionIDMgr{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Increment the connection count
|
|
|
|
|
func (c *sessionIDMgr) Increment() {
|
|
|
|
|
atomic.AddInt64(&c.count, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decrement the connection count
|
|
|
|
|
func (c *sessionIDMgr) Decrement() {
|
|
|
|
|
atomic.AddInt64(&c.count, -1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Count returns the connection numbers in current
|
|
|
|
|
func (c *sessionIDMgr) Count() int64 {
|
|
|
|
|
return atomic.LoadInt64(&c.count)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset the connection service status
|
|
|
|
|
func (c *sessionIDMgr) Reset() {
|
|
|
|
|
atomic.StoreInt64(&c.count, 0)
|
|
|
|
|
atomic.StoreInt64(&c.sid, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SessionID returns the session id
|
|
|
|
|
func (c *sessionIDMgr) SessionID() int64 {
|
|
|
|
|
return atomic.AddInt64(&c.sid, 1)
|
|
|
|
|
}
|