聊天负责私人聊天,群组聊天。私人聊天接受信息后保存至数据库再转发给目标用户。群组聊天当前没有离线消息保存,也就是用户登录后无法知道多少消息未读,而是直接拉取指定数量群聊天。当有成员发送后会将聊天信息存储数据库(没有缓存进redis,因为在线用户会直接发送,目前没有这个优化必要),从redis中检索所有群组在线用户并通过消息队列发送至对应网关。
大致代码如下:
// 处理群消息
func DealGroupMsg(delivery *amqp.Delivery, transfer1 *transfer) {
now := time.Now()
Userid := transfer1.Id
var mess SendMessage
err := mapstructure.Decode(transfer1.Data.Data, &mess)
if err != nil {
fmt.Println("DealGroupMsg json err :", err)
return
}
if mess.UserId != Userid {
fmt.Println("DealGroupMsg 发送者id不一致 ", mess.UserId, "--", Userid)
// delivery.Ack(true)
return
}
ItemId := mess.To
if mess.MsgType != GroupMessage {
fmt.Println("DealGroupMsg 信息类型不一致 ", mess.MsgType, "--", Userid)
// delivery.Ack(true)
return
}
// 判断用户是否为群成员
r, err := IsGroupMember(Userid, ItemId)
if err != nil {
fmt.Println("DealGroupMsg json err :", err)
return
}
if !r {
fmt.Println("DealGroupMsg 不属于群成员 ", mess.To, "--", Userid)
// delivery.Ack(true)
return
}
// 获取全局id
id, err := redisconn.GetGlobalID()
if err != nil {
fmt.Println("DealGroupMsg json err :", err)
return
}
//fmt.Println(id)
// time.Sleep(4 * time.Second)
// 获取当前时间戳
ti := time.Now().UnixNano() / 1e6
Msgid1 := strconv.FormatInt(ti, 10) + fmt.Sprintf("%06d", id)
mess.Id = Msgid1
// 将id 发送给发信息者
var sendmessagereply SendMessageReply
sendmessagereply.Id = Msgid1
sendmessagereply.MsgReplyID = mess.MsgReplyID
sendmessagereply.To = mess.To
sendmessagereply.MsgType = GroupMessage
nowtime := time.Now().UnixNano() / 1e6
// 如果发送时间差值小于2S 选用发送者时间 否则选择后台时间
UserSendTime, err := strconv.ParseInt(mess.SendTime, 10, 64)
if err != nil {
fmt.Println("DealGroupMsg", err)
return
}
var ReplyTime string
if Abs(UserSendTime-nowtime) < 1000*2 {
ReplyTime = strconv.FormatInt(UserSendTime, 10)
} else {
ReplyTime = strconv.FormatInt(nowtime, 10)
}
sendmessagereply.ReplyTime = ReplyTime
var json = jsoniter.ConfigCompatibleWithStandardLibrary
data2, err := json.Marshal(sendmessagereply)
if err != nil {
fmt.Println("DealGroupMsg", err)
return
}
time11 := time.Now()
err = RabbitMqPublish(mq, data2, Userid, SendGroupMsgAckReply, transfer1.From)
if err != nil {
fmt.Println("DealGroupMsg", err)
return
}
fmt.Println("RabbitMqPublish", time.Now().Sub(time11))
// 查询群成员
// delivery.Ack(true)
var rmsg ReceiveMessage
rmsg.Id = Msgid1
rmsg.MsgData = mess.MsgData
rmsg.MsgDataType = mess.MsgDataType
rmsg.MsgType = GroupMessage
rmsg.To = mess.To
rmsg.UserId = mess.UserId
rmsg.SendTime = ReplyTime
// 使用Mysql存储起来
go InsertMessages(rmsg)
// err = msql.InsertChatMessage(Msgid1, mess.UserId, mess.To, mess.MsgData, mess.MsgType, mess.MsgDataType, ReplyTime)
// if err != nil {
// fmt.Println("DealGroupMsg e", Msgid1, err)
// return
// }
fmt.Println("DealGroupMsg", time.Now().Sub(now))
go DealGroupMessage(ItemId, rmsg)
}
// 群成员发送信息后后续处理
func DealGroupMessage(GroupId string, Msg ReceiveMessage) {
now := time.Now()
// 获取群成员 在线则发送
members, err := GetGroupMemberListSimply(GroupId)
if err != nil {
fmt.Println("DealGroupMessage", err)
return
}
data2, err := json.Marshal(Msg)
if err != nil {
fmt.Println("DealGroupMessage", err)
return
}
for _, member := range members {
// 获取用户信息
u, err := redisconn.RedisGetUser(member.User.Userid)
if err != nil {
fmt.Println("DealGroupMessage", err)
continue
}
//如果群成员在线则发送
if u.Status == OnLine {
// fmt.Println("Send")
err = RabbitMqPublish(mq, data2, u.Userid, ReceiveGroupMsg, u.GateWay)
if err != nil {
fmt.Println("AddUserDeal", err)
return
}
}
}
fmt.Println("DealGroupMessage", time.Now().Sub(now))
}