func (this *MsgServer) HandleLoginResult(msg *msgcmd.Cmd) { //根据回馈信息的第一个参数,查找那个用户的信息 user := this.FindUser(msg.Args[0]) //临时用户名 if user == nil { println("Msg Server Error: 查找指定用户时 失败. %s", msg.Args[0]) logFile.Printf("Msg Server Error: 查找指定用户时 失败. %s", msg.Args[0]) return } //给Client返回结果 //构造新的消息 resMsg := msgcmd.NewCmd(msgcmd.MCMD_M2C_LOGIN) resMsg.AddArg(msg.Args[1]) if msg.Args[1] == "1" { //先将原来的map项删除 this.userlist.Delete(user.Name) //登陆成功,更改MS上该用户的信息 user.SetIDbyString(msg.Args[2]) user.Name = msg.Args[3] user.State = 1 //将更新后的user数据重新加入用户列表中 this.userlist.Insert(user.Name, user) } //通知对应的Client,结果信息 if err := user.Session.Send(resMsg); err != nil { println("Msg Server Error: 发送用户登陆响应时 失败. %s", msg.Args[3]) logFile.Printf("Msg Server Error: 发送用户登陆响应时 失败. %s", msg.Args[3]) return } }
func (this *WorldServer) DoHeartBeat(session *libnet.Session) { //发送心跳响应信息 heartMsg := msgcmd.NewCmd(msgcmd.MCMD_W2M_HEARTBEAT) if err := session.Send(heartMsg); err != nil { println("World Server Error: 响应 MsgServer 心跳信息 失败. ") logFile.Printf("World Server Error: 响应 MsgServer 心跳信息 失败. ") return } }
func (this *MsgServer) DoHeartBeat(msg *msgcmd.Cmd, user *common.UserInfo) { //println("[Client -> MS] 心跳信息") hmsg := msgcmd.NewCmd(msgcmd.MCMD_M2C_HEARTBEAT) //收到用户心跳消息,原样返回心跳消息 if err := user.Session.Send(hmsg); err != nil { println("Msg Server Error: 发送心跳响应信息 失败. ", err.Error()) logFile.Printf("Msg Server Error: 发送心跳响应信息 失败. ", err.Error()) return } }
func (this *MsgServer) HandleKeyClient(session *libnet.Session) { defer waitgroup.Done() defer session.Close() //Client 连接 Msg Key Server 后, 发送 RC4 秘钥给 Client cmd := msgcmd.NewCmd(msgcmd.MCMD_RESPONSERC4KEY) cmd.AddArg(this.customCodec.GetKey()) if err := session.Send(cmd); err != nil { println("Msg Key Server Error: 发送 RC4 Key 失败. ", err.Error()) logFile.Printf("Msg Key Server Error: 发送 RC4 Key 失败. ", err.Error()) return } }
func (this *WorldServer) HandleKeyClient(session *libnet.Session) { defer waitgroup.Done() defer session.Close() //Msg Server 连接 WS 的 Key Server 后,WS 发送 RC4 秘钥给 Msg Server cmd := msgcmd.NewCmd(msgcmd.MCMD_RESPONSERC4KEY) cmd.AddArg(this.cfg.Rc4Key) if err := session.Send(cmd); err != nil { println("World Server Error: 发送 RC4 Key 失败. ", err.Error()) logFile.Printf("World Server Error: 发送 RC4 Key 失败. ", err.Error()) return } }
func (this *Client) HandleLogin(msg *msgcmd.Cmd) { if msg.Args[0] == "1" { println("登陆成功!") //设置本地用户在线状态 this.user.State = 1 //主动请求一下当前在线用户的列表 reqMsg := msgcmd.NewCmd(msgcmd.MCMD_C2M_REQUEST_ONLINEUSERS) if err := this.session.Send(reqMsg); err != nil { println("Client Error: 发送获取在线用户列表请求 失败. ", err.Error()) logfile.Printf("Client Error: 发送获取在线用户列表请求 失败. %s", err.Error()) } } else { println("登陆失败!") } }
func (this *WorldServer) DoRequestOnlineUsers(msg *msgcmd.Cmd, session *libnet.Session) { resMsg := msgcmd.NewCmd(msgcmd.MCMD_W2M_RESPONSE_ONLINEUSERS) resMsg.AddArg(msg.Args[0]) //发起这个请求的用户的用户名 userlist := usermap.CopyData() for _, value := range userlist { if user, ok := value.(*common.UserInfo); ok { if user.State == 1 { resMsg.AddArg(user.Name) } } } if err := session.Send(resMsg); err != nil { println("World Server Error: 发送 在线用户列表信息 失败. ") logFile.Printf("World Server Error: 发送 在线用户列表信息 失败. ") } }
func (this *Gateway) HandleClient(session *libnet.Session, index uint) { defer waitgroup.Done() defer session.Close() var serverAddr string = this.cfg.MsgServerList[index] var keyAddr string = getKeyServerAddr(serverAddr) //主动应答 MS Server Addr 和 Key Server Addr 给 Client cmd := msgcmd.NewCmd(msgcmd.MCMD_G2C_RESPONSEMSADDR) cmd.AddArg(serverAddr) cmd.AddArg(keyAddr) if err := session.Send(cmd); err != nil { println("GateWay Error: 发送Msg Server 地址信息失败. ", err.Error()) logFile.Printf("GateWay Error: 发送Msg Server 地址信息失败. %s", err.Error()) return } }
func (this *MsgServer) DoClientExit(user *common.UserInfo) { //通知WS有用户下线 if user.State == 1 { user.State = 0 println("[Client -> MS] 用户下线:", user.Name) offlinemsg := msgcmd.NewCmd(msgcmd.MCMD_M2W_USEROFFLINE) offlinemsg.AddArg(user.Name) if err := this.wsSession.Send(offlinemsg); err != nil { println("Msg Server Error: 发送用户下线信息 失败. ", err.Error()) logFile.Printf("Msg Server Error: 发送用户下线信息 失败. ", err.Error()) return } } //MS 清除该用户信息 this.userlist.Delete(user.Name) }
func (this *MsgServer) HandleRegisterResult(msg *msgcmd.Cmd) { //根据回馈信息的第一个参数,查找那个用户的信息 user := this.FindUser(msg.Args[0]) if user == nil { println("Msg Server Error: 查找指定用户时 失败. %s", msg.Args[0]) logFile.Printf("Msg Server Error: 查找指定用户时 失败. %s", msg.Args[0]) return } //给Client返回结果 resMsg := msgcmd.NewCmd(msgcmd.MCMD_M2C_REGISTER) resMsg.AddArg(msg.Args[1]) resMsg.AddArg(msg.Args[2]) if err := user.Session.Send(resMsg); err != nil { println("Msg Server Error: 发送注册结果信息 失败. ", err.Error()) logFile.Printf("Msg Server Error: 发送注册结果信息 失败. ", err.Error()) return } }
func (this *WorldServer) DoUserOffline(msg *msgcmd.Cmd, session *libnet.Session) { if user, found := usermap.Find(msg.Args[0]); found { //设置用户状态 if userinfo, ok := user.(*common.UserInfo); ok { userinfo.State = 0 userinfo.UpdateTimestamp() println("[MS --> WS]:用户下线,", userinfo.Name) //广播所有用户,有用户下线 bcMsg := msgcmd.NewCmd(msgcmd.MCMD_W2M_BROADCAST) bcMsg.AddArg(msgcmd.IntToString(msgcmd.ECMD_BROADCAST_USEROFFLINE)) bcMsg.AddArg(userinfo.Name) this.Broadcast(bcMsg) } else { println("World Server Error: (*common.UserInfo) 类型断言 失败. ") logFile.Printf("World Server Error: (*common.UserInfo) 类型断言 失败. ") return } } }
func (this *WorldServer) DoRegister(msg *msgcmd.Cmd, session *libnet.Session) { resmsg := msgcmd.NewCmd(msgcmd.MCMD_W2M_REGISTER) resmsg.AddArg(msg.Args[2]) //在返回的消息中,附上传入的临时用户名 //查找是否已经存在该用户名 row := this.database.QueryData(`SELECT * FROM users WHERE name=?`, msg.Args[0]) var userinfo *common.UserInfo = common.NewUserInfo(session) if err := row.Scan(&userinfo.ID, &userinfo.Name, &userinfo.Pwd, &userinfo.RegDate); err == sql.ErrNoRows { //可注册该用户名 userinfo.RegDate = time.Now() err = this.database.InsertData(`INSERT users (name,pwd,regdate) values (?,?,?)`, msg.Args[0], msg.Args[1], userinfo.RegDate) if err != nil { //插入数据失败,返回提示信息 println("World Server Error: 写入注册信息 失败. ", err.Error()) logFile.Printf("World Server Error: 写入注册信息 失败. ", err.Error()) resmsg.AddArg("0") resmsg.AddArg("注册用户时发生异常,请稍后再试。") if err = session.Send(resmsg); err != nil { println("World Server Error: 发送注册回馈信息 失败. ", err.Error()) logFile.Printf("World Server Error: 发送注册回馈信息 失败. ", err.Error()) return } } else { resmsg.AddArg("1") resmsg.AddArg("注册用户成功,试试登陆吧。") if err = session.Send(resmsg); err != nil { println("World Server Error: 发送注册回馈信息 失败. ", err.Error()) logFile.Printf("World Server Error: 发送注册回馈信息 失败. ", err.Error()) return } } } else { //不可注册该用户名 resmsg.AddArg("0") resmsg.AddArg("该用户名已被抢先1秒注册,换个试试吧。") if err = session.Send(resmsg); err != nil { println("World Server Error: 发送注册回馈信息 失败. ", err.Error()) logFile.Printf("World Server Error: 发送注册回馈信息 失败. ", err.Error()) return } } }
func (this *Client) DoLogin() { println("<< -- 用户登陆 -- >>") print("用户名:") this.user.Name = readString() print("密 码:") this.user.Pwd = readString() this.user.Pwd = common.SHA1(this.user.Pwd) //封装登陆消息 loginMsg := msgcmd.NewCmd(msgcmd.MCMD_C2M_LOGIN) loginMsg.AddArg(this.user.Name) loginMsg.AddArg(this.user.Pwd) //发送数据给Msg Server if err := this.session.Send(loginMsg); err != nil { println("Client Error: 发送用户登陆信息失败. ", err.Error()) logfile.Printf("Client Error: 发送用户登陆信息失败. %s", err.Error()) return } }
/* * 描 述: 处理用户注册请求 * 参 数: 无 * 返回值: 无 */ func (this *Client) DoRegister() { println("<< -- 注册用户 -- >>") print("输入用户名:") username := readString() print("设定密码:") password := readString() password = common.SHA1(password) //封装注册消息 registerMsg := msgcmd.NewCmd(msgcmd.MCMD_C2M_REGISTER) registerMsg.AddArg(username) registerMsg.AddArg(password) //发送数据给Msg Server if err := this.session.Send(registerMsg); err != nil { println("Client Error: 发送用户注册信息失败. ", err.Error()) logfile.Printf("Client Error: 发送用户注册信息失败. %s", err.Error()) return } }
func (this *WorldServer) DoLogin(msg *msgcmd.Cmd, session *libnet.Session) { resmsg := msgcmd.NewCmd(msgcmd.MCMD_W2M_LOGIN) resmsg.AddArg(msg.Args[2]) var userinfo *common.UserInfo var isInUserMap = false var result bool if user, ok := usermap.Find(msg.Args[0]); ok { if userinfo, result = user.(*common.UserInfo); !result { println("World Server Error: (*common.UserInfo) 类型断言 失败. ") logFile.Printf("World Server Error: (*common.UserInfo) 类型断言 失败. ") return } isInUserMap = true } else { //查找是否已经存在该用户名 row := this.database.QueryData(`SELECT * FROM users WHERE name=?`, msg.Args[0]) userinfo = common.NewUserInfo(session) if err := row.Scan(&userinfo.ID, &userinfo.Name, &userinfo.Pwd, &userinfo.RegDate); err == sql.ErrNoRows { //登陆失败,没有该用户信息 resmsg.AddArg("0") if err = session.Send(resmsg); err != nil { println("World Server Error: 发送登陆回馈信息 失败. ", err.Error()) logFile.Printf("World Server Error: 发送登陆回馈信息 失败. ", err.Error()) return } } } //找到该用户数据,开始验证密码信息 if userinfo.Name == msg.Args[0] && userinfo.Pwd == msg.Args[1] { //登陆成功 resmsg.AddArg("1") resmsg.AddArg(userinfo.GetIDbyString()) resmsg.AddArg(userinfo.Name) if err := session.Send(resmsg); err != nil { println("World Server Error: 发送登陆回馈信息 失败. ", err.Error()) logFile.Printf("World Server Error: 发送登陆回馈信息 失败. ", err.Error()) return } userinfo.State = 1 } else { //登陆失败 resmsg.AddArg("0") if err := session.Send(resmsg); err != nil { println("World Server Error: 发送登陆回馈信息 失败. ", err.Error()) logFile.Printf("World Server Error: 发送登陆回馈信息 失败. ", err.Error()) return } userinfo.State = 0 } if userinfo.State == 1 { //有用户上线,广播所有用户 bcMsg := msgcmd.NewCmd(msgcmd.MCMD_W2M_BROADCAST) bcMsg.AddArg(msgcmd.IntToString(msgcmd.ECMD_BROADCAST_USERLOGIN)) bcMsg.AddArg(userinfo.Name) this.Broadcast(bcMsg) } //保存当前用户所在的MS会话地址 userinfo.Session = session //添加到usermap中 if !isInUserMap { usermap.Insert(userinfo.Name, userinfo) } }
func (this *Client) DoExit() { timeoutmsg := msgcmd.NewCmd(msgcmd.MCMD_TIMEOUT) this.MsgChan <- timeoutmsg }
func (this *MsgServer) HandleClient(session *libnet.Session) { defer waitgroup.Done() //创建一个“匿名用户”,并添加到MS的用户列表中 user := common.NewUserInfo(session) user.MsgChan = make(chan *msgcmd.Cmd, 1024) //插入到用户列表中 this.userlist.Insert(user.Name, user) var isRun bool = true //开一个单独的协程,负责等待Client消息 go func() { for isRun { msg := new(msgcmd.Cmd) if session.IsClosed() { return } err := session.Receive(msg) if err != nil { if err == io.EOF { //Client 关闭了会话 msg.Mid = msgcmd.MCMD_C2M_CLIENTEXIT println("Client 关闭了会话") isRun = false } println("Msg Server Error: 接收数据 失败. ", err.Error()) logFile.Printf("Msg Server Error: 接收数据 失败. ", err.Error()) } user.MsgChan <- msg } }() FORLOOP: for { timer := time.NewTimer(this.cfg.Expire * time.Second) var msg *msgcmd.Cmd select { case msg = <-user.MsgChan: case <-timer.C: //接收客户端消息超时,客户端未做任何操作,同时没有心跳包发送过来,判定用户已经离线 msg = msgcmd.NewCmd(msgcmd.MCMD_C2M_CLIENTEXIT) println("客户端操作超时") } timer.Stop() switch msg.Mid { case msgcmd.MCMD_C2M_REGISTER: this.DoRegister(msg, user) case msgcmd.MCMD_C2M_LOGIN: this.DoLogin(msg, user) case msgcmd.MCMD_C2M_HEARTBEAT: this.DoHeartBeat(msg, user) case msgcmd.MCMD_C2M_REQUEST_ONLINEUSERS: this.DoRequestOnlineUsers(msg, user) case msgcmd.MCMD_C2M_CLIENTEXIT: this.DoClientExit(user) break FORLOOP default: if msg != nil { println("好像接收到了什么...") } } } println("用户Go程退出") }
func (this *Client) Run() { //Client 接收 Msg Server 的消息 defer waitgroup.Done() var sendtimer *time.Timer var waittimer *time.Timer go func() { for { msg := new(msgcmd.Cmd) if err := this.session.Receive(msg); err != nil { if err != libnet.ErrClosed { println("Client Error: 接收数据 失败. ", err.Error()) logfile.Printf("Client Error: 接收数据 失败. %s", err.Error()) } return } this.MsgChan <- msg } }() //FORLOOP: for { sendtimer = time.NewTimer(this.cfg.Expire * time.Second) var msg *msgcmd.Cmd if this.isSentHeartBeat == true { waittimer = time.NewTimer(this.cfg.Expire * 2 * time.Second) select { case msg = <-this.MsgChan: case <-waittimer.C: //接收MS的心跳响应超时 timeoutmsg := msgcmd.NewCmd(msgcmd.MCMD_TIMEOUT) this.MsgChan <- timeoutmsg } this.isSentHeartBeat = false waittimer.Stop() } else { select { case msg = <-this.MsgChan: case <-sendtimer.C: //超时没有收到WS的消息,发送一个心跳包 //println("[Client -> MS] 心跳信息") beatmsg := msgcmd.NewCmd(msgcmd.MCMD_C2M_HEARTBEAT) if err := this.session.Send(beatmsg); err != nil { println("Client Error: 发送心跳信息 失败. ", err.Error()) logfile.Printf("Client Error: 发送心跳信息 失败. ", err.Error()) return } this.isSentHeartBeat = true //表示已经发送了心跳包 } sendtimer.Stop() } if msg == nil { continue } switch msg.Mid { case msgcmd.MCMD_M2C_REGISTER: this.HandleRegister(msg) case msgcmd.MCMD_M2C_LOGIN: this.HandleLogin(msg) case msgcmd.MCMD_M2C_BROADCAST: this.HandleBroadCast(msg) case msgcmd.MCMD_M2C_RESPONSE_ONLINEUSERS: this.HandleReqOnlineUsers(msg) case msgcmd.MCMD_TIMEOUT: println("[Client !<- MS] 心跳响应信息") this.session.Close() return } } }
func (this *MsgServer) Run() { //Msg Server 接收 World Server的消息 defer waitgroup.Done() var sendtimer *time.Timer var waittimer *time.Timer msgChan := make(chan *msgcmd.Cmd, 1024) go func() { for { msg := new(msgcmd.Cmd) if err := this.wsSession.Receive(msg); err != nil { println("Client Error: 接收数据 失败. ", err.Error()) logFile.Printf("Client Error: 接收数据 失败. %s", err.Error()) return } msgChan <- msg } }() //FORLOOP: for { sendtimer = time.NewTimer(this.cfg.Expire * time.Second) var msg *msgcmd.Cmd if this.isSentHeartBeat == true { waittimer = time.NewTimer(this.cfg.Expire * 2 * time.Second) select { case msg = <-msgChan: case <-waittimer.C: //接收WS的心跳响应超时 timeoutmsg := msgcmd.NewCmd(msgcmd.MCMD_TIMEOUT) msgChan <- timeoutmsg } this.isSentHeartBeat = false waittimer.Stop() } else { select { case msg = <-msgChan: case <-sendtimer.C: //超时没有收到WS的消息,发送一个心跳包 //println("[MS -> WS] 心跳信息") beatmsg := msgcmd.NewCmd(msgcmd.MCMD_M2W_HEARTBEAT) if err := this.wsSession.Send(beatmsg); err != nil { println("Msg Server Error: 发送心跳信息 失败. ", err.Error()) logFile.Printf("Msg Server Error: 发送心跳信息 失败. ", err.Error()) return } this.isSentHeartBeat = true //表示已经发送了心跳包 } sendtimer.Stop() } if msg == nil { continue } switch msg.Mid { case msgcmd.MCMD_W2M_BROADCAST: //this.HandleBroadCast(msg) this.BroadCastToAllUser(msg) case msgcmd.MCMD_W2M_REGISTER: this.HandleRegisterResult(msg) case msgcmd.MCMD_W2M_LOGIN: this.HandleLoginResult(msg) case msgcmd.MCMD_W2M_RESPONSE_ONLINEUSERS: this.HandleReqOnlineUsers(msg) case msgcmd.MCMD_TIMEOUT: println("[MS !<- WS] 心跳响应信息") case msgcmd.MCMD_W2M_HEARTBEAT: //println("收到WS心跳响应,MS处于正常状态...") } } }