func receiveMessagePacket(uid uint64, imDB imdatabase.ImDb) { userUid := uid qfor: for { ClientSession, flag := SessionTable[userUid] if flag == false { ImServerLog("user session doesn't exist.", userUid) ///////// return } select { case pp := <-ClientSession.incoming: //提取出来的是 protobuf对象 从对象里面提取出所要的信息改session层的 name,id... { ttype := pp.GetType() //对型号为 2,4,5 进行处理。 pcmd, err := GetCommand(&pp) if err != nil { ImServerLog("GetCommand err when read type 1 packet" + err.Error()) break } random2and4p := pcmd.Message.GetRandom() dialogId := pcmd.GetReceiver() // dialogUid message := pcmd.Message.GetData() //ImPacketInTime(userUid, message, time.Now().UnixNano()) //纪录读到的包 Beat(userUid) if ttype == 1 { *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = random2and4p *returnCMD.Message.Data = string(ttype) + ":had login before!" logagainreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *logagainreturnPacket break } if ttype == 5 { // 心跳包,读取name就ok } if ttype == 3 { //客户端收到信息后返回服务端4号包表示确认收到 FeedBack.DeleteOne(random2and4p) } if ttype == 2 || ttype == 4 { // 信息包或者文件包 *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = random2and4p *returnCMD.Message.Data = string(ttype) + ":Server received successfully." receivesucessreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *receivesucessreturnPacket /*err := imDB.AddMessage(userUid, dialogId, pp.GetType(), message, time.Now().Format("2006-01-02 15:04:05")) if err != nil { fmt.Println("AddMessage to mysql err", err) *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = 1 *returnCMD.Message.Data = "IM Server Error!" sqlerrreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *sqlerrreturnPacket ImServerLog("IM Server Error! Because read outlinemessage err") break }*/ ImPacketInTime(userUid, message, time.Now().UnixNano()) //记录消息和在线则转发,不在线则存离线.如果dialog是活跃的才发送;转发给Dialog 里面其他所有人. //ImServerLog("Receive a message as", ttype, "User : "******". DialogId : ", dialogId) receivers, flag := ClientSession.chatMap[dialogId] if flag == true { //在chatMap里面能够找到对应的表,则发送给表内所有成员 for _, receiverUid := range receivers { sess, fl := SessionTable[receiverUid] //在线 if fl == true { //ImServerLog("Write feedback to user : "******". Server received successfully") /////////////////////////////////////// //重新制作包发给另一端 *messageCMD.Sender = dialogId *messageCMD.Receiver = receiverUid *messageCMD.Message.Data = message *messageCMD.Message.Random = GenRandom() sendPacket := MakePacket(messageCMD, ttype) sess.outgoing <- *sendPacket continue //写入数据库message表 message } //用户不在线,存离线outlinemessage *messageCMD.Sender = dialogId *messageCMD.Receiver = receiverUid *messageCMD.Message.Data = message *messageCMD.Message.Random = GenRandom() outLineMsg := MakePacket(messageCMD, ttype) err := imDB.AddOutlineMsg(receiverUid, uint32(ttype), outLineMsg.GetData(), time.Now().Format("2006-01-02 15:04:05")) if err != nil { *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = 1 *returnCMD.Message.Data = "IM Server Error!" mysqlerrreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *mysqlerrreturnPacket //ImServerLog("IM Server Error! Because read outlinemessage err") continue } //*returnCMD.Sender = 0 //*returnCMD.Receiver = userUid //*returnCMD.Message.Random = random2and4p //*returnCMD.Message.Data = string(ttype) + ":receiver isn't online!" //returnPacket := MakePacket(returnCMD, 3) //ClientSession.outgoing <- *returnPacket //ImServerLog("Write feedback to user : "******". Receiver isn't online!") ////////////////////////////////////////////////// } break } //没能在chatMap里面找到,则先扫描activedialog表,若没有则告诉客户端 if ClientSession.chatMap[dialogId] == nil { //初始化chatmap对应的切片 ClientSession.chatMap[dialogId] = make([]uint64, 0, MaxMemberInGroup) } actDialogTable, err := imDB.Db.Query("select * from act_dialog where dialog_id=? order by dialog_id", dialogId) if err != nil { *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = 1 *returnCMD.Message.Data = "IM Server Error!" queryerrreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *queryerrreturnPacket break } defer actDialogTable.Close() if actDialogTable.Next() { //这里由于数据库定好了act_dialog 的唯一性,所以存在也只会存在一次,用if足够 //查询dialog表//查询条件:dialog,时间戳为0,返回没有被踢群的用户 activeUserTable, err := imDB.Db.Query("select uid from dialog where dialog_Id=? and timestamp=?", dialogId, "0000-00-00 00:00:00") if err != nil { *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = 1 *returnCMD.Message.Data = "IM Server Error!" errorreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *errorreturnPacket break } defer activeUserTable.Close() var uid uint64 var flaguidin bool //用户在群内 for activeUserTable.Next() { err = activeUserTable.Scan(&uid) //没有被踢群的用户 if err != nil { *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = 1 *returnCMD.Message.Data = "IM Server Error!" errreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *errreturnPacket DatabaseLog("Database error in scaning dialog:" + err.Error()) break } //****************************成员加入到chatMap if uid == userUid { flaguidin = true //自己在群内,则flaguid为true continue } ClientSession.chatMap[dialogId] = append(ClientSession.chatMap[dialogId], uid) } if flaguidin != true { //自己已被踢出群 delete(ClientSession.chatMap, dialogId) //删除chatMap //这里发给用户一个命令包 type6 用户那边显示并且不能往该dialog 发送内容 *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = random2and4p *returnCMD.Message.Data = string(ttype) + ":you are out of group!" outofgroupreturnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *outofgroupreturnPacket break } //自己在群内,向chatMap里的uid转发消息 for _, receiverUid := range ClientSession.chatMap[dialogId] { sess, fl := SessionTable[receiverUid] if fl == true { //重新制作包发给另一端 *messageCMD.Sender = dialogId *messageCMD.Receiver = receiverUid *messageCMD.Message.Data = message *messageCMD.Message.Random = GenRandom() sendaPacket := MakePacket(messageCMD, ttype) sess.outgoing <- *sendaPacket continue } //用户不在线,存离线outlinemessage *messageCMD.Sender = dialogId *messageCMD.Receiver = receiverUid *messageCMD.Message.Data = message *messageCMD.Message.Random = GenRandom() outLineMsg2 := MakePacket(messageCMD, ttype) err := imDB.AddOutlineMsg(receiverUid, uint32(ttype), outLineMsg2.GetData(), time.Now().Format("2006-01-02 15:04:05")) if err != nil { //fmt.Println("AddOutlinemessage to mysql err", err) *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = 1 *returnCMD.Message.Data = "IM Server Error!" returnPacket := MakePacket(returnCMD, 3) ClientSession.outgoing <- *returnPacket ImServerLog("IM Server Error! Because read outlinemessage err", err) continue } } break } //act_dialog找不到 *returnCMD.Sender = 0 *returnCMD.Receiver = userUid *returnCMD.Message.Random = random2and4p *returnCMD.Message.Data = string(ttype) + ":dialog isn't active!" returnPacket3 := MakePacket(returnCMD, 3) ClientSession.outgoing <- *returnPacket3 } _, fla := SessionTable[userUid] if fla == true { SessionTable[userUid] = ClientSession } } case <-ClientSession.quitfor: { //回馈包??? break qfor } } } }