Skip to content

Commit

Permalink
fixed session bug
Browse files Browse the repository at this point in the history
  • Loading branch information
cuixin committed Apr 1, 2015
1 parent 3b67151 commit c43ec2e
Showing 1 changed file with 65 additions and 32 deletions.
97 changes: 65 additions & 32 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"os"
"sync"
"time"

msgpack "gopkg.in/vmihailenco/msgpack.v2"
)

Expand All @@ -23,15 +22,45 @@ func NewSessionId(size int) string {

// 用户会话
type Session struct {
Sid string // 用户SessionId
mu sync.Mutex `msgpack:"-"`
Sid string // 用户SessionId
Uid string // 用户Uid
RemoteAddr string // 远程连接地址
ConnectTime time.Time // 连接时间
LastPacketTime time.Time // 最后一次发包时间,判定是否玩家已经超时离线
PacketCount int64 // 发送请求包的总数量
Attachment interface{} `msgpack:"-"` // 绑定的数据
DownQueue *SafeQueue `msgpack:"-"` // 下行数据的队列
MsgQueue chan *Message `msgpack:"-"` // 消息
msgQ chan *Message `msgpack:"-"` // 消息队列
isClosed bool
}

func (this *Session) closeMsgQ() {
this.mu.Lock()
if !this.isClosed {
this.isClosed = true
}
close(this.msgQ)
this.mu.Unlock()
}

// 发送消息
func (this *Session) SendMessage(msg *Message) bool {
isSend := false
this.mu.Lock()
if !this.isClosed {
isSend = true
this.msgQ <- msg
if msg.IsDown != nil {
msg.IsDown <- struct{}{}
}
}
this.mu.Unlock()
return isSend
}

func (this *Session) GetMsgQ() <-chan *Message {
return this.msgQ
}

// 实现一个双向唯一Sid<->Uid
Expand All @@ -49,7 +78,7 @@ type Message struct {
}

type SessionManager struct {
sync.Mutex
mu sync.Mutex
sidMaps map[string]*Session // SessionId ----> Session
uidMaps map[string]*Session // Uid ----> Session
}
Expand All @@ -58,124 +87,126 @@ func (this *SessionManager) NewSession(uid, remoteAddr string) (*Session, bool)
sid := NewSessionId(32)
nowTime := time.Now()
s := &Session{
mu : sync.Mutex{},
Sid: sid,
Uid: uid,
RemoteAddr: remoteAddr,
ConnectTime: nowTime,
LastPacketTime: nowTime,
PacketCount: 1,
DownQueue: NewSafeQueue(),
MsgQueue: make(chan *Message, 16),
msgQ: make(chan *Message, 16),
isClosed: false,
}
this.Lock()
this.mu.Lock()
if oldSession, ok := this.sidMaps[sid]; ok {
sid = NewSessionId(32)
if oldSession2, ok2 := this.sidMaps[sid]; ok2 {
this.Unlock()
this.mu.Unlock()
return oldSession2, false
} else {
s.Sid = sid
this.sidMaps[sid] = s
this.uidMaps[uid] = s
this.Unlock()
this.mu.Unlock()
return s, true
}
this.Unlock()
this.mu.Unlock()
return oldSession, false
}
if oldSession, ok := this.uidMaps[uid]; ok {
this.Unlock()
this.mu.Unlock()
return oldSession, false
}
this.sidMaps[sid] = s
this.uidMaps[uid] = s
this.Unlock()
this.mu.Unlock()
return s, true
}

func (this *SessionManager) GetAllSessionUids() []string {
this.Lock()
sLen := len(this.uidMaps)
this.mu.Lock()
sLen := len(this.uidMaps)
ret := make([]string, sLen)
i := 0
for uid, _ := range this.uidMaps {
ret[i] = uid
i++
}
this.Unlock()
this.mu.Unlock()
return ret
}

func (this *SessionManager) GetAllSessionSids() []string {
this.Lock()
this.mu.Lock()
sLen := len(this.sidMaps)
ret := make([]string, sLen)
i := 0
for sid, _ := range this.sidMaps {
ret[i] = sid
i++
}
this.Unlock()
this.mu.Unlock()
return ret
}

func (this *SessionManager) ClearSession() {
this.Lock()
this.mu.Lock()
this.uidMaps = nil
this.uidMaps = make(map[string]*Session, 16<<10)
this.sidMaps = nil
this.sidMaps = make(map[string]*Session, 16<<10)
this.Unlock()
this.mu.Unlock()
}

func (this *SessionManager) GetSessionBySid(sid string) *Session {
this.Lock()
this.mu.Lock()
ret := this.sidMaps[sid]
this.Unlock()
this.mu.Unlock()
return ret
}

func (this *SessionManager) GetSessionByUid(uid string) *Session {
this.Lock()
this.mu.Lock()
ret := this.uidMaps[uid]
this.Unlock()
this.mu.Unlock()
return ret
}

func (this *SessionManager) GetSessionCount() int {
this.Lock()
this.mu.Lock()
ret := len(this.sidMaps)
this.Unlock()
this.mu.Unlock()
return ret
}

func (this *SessionManager) RemoveSession(s *Session) {
this.Lock()
this.mu.Lock()
delete(this.sidMaps, s.Sid)
delete(this.uidMaps, s.Uid)
close(s.MsgQueue)
this.Unlock()
this.mu.Unlock()
s.closeMsgQ()
}

func (this *SessionManager) RemoveSessionBySid(sid string) *Session {
this.Lock()
this.mu.Lock()
s, ok := this.sidMaps[sid]
if ok {
delete(this.sidMaps, sid)
delete(this.uidMaps, s.Uid)
}
this.Unlock()
this.mu.Unlock()
return s
}

func (this *SessionManager) RemoveSessionByUid(uid string) *Session {
this.Lock()
this.mu.Lock()
s, ok := this.uidMaps[uid]
if ok {
delete(this.sidMaps, s.Sid)
delete(this.uidMaps, uid)
}
this.Unlock()
this.mu.Unlock()
return s
}

Expand Down Expand Up @@ -218,8 +249,10 @@ func (this *SessionManager) LoadFromFile(filePath string) (int, error) {
msgpack.Unmarshal(data, &this.sidMaps)
l1 := len(this.sidMaps)
for _, v := range this.sidMaps {
v.MsgQueue = make(chan *Message, 16)
v.mu = sync.Mutex{}
v.msgQ = make(chan *Message, 16)
v.DownQueue = NewSafeQueue()
v.isClosed = false
this.uidMaps[v.Uid] = v
}
return l1, nil
Expand Down

0 comments on commit c43ec2e

Please sign in to comment.