简易聊天系统-聊天服务

聊天负责私人聊天,群组聊天。私人聊天接受信息后保存至数据库再转发给目标用户。群组聊天当前没有离线消息保存,也就是用户登录后无法知道多少消息未读,而是直接拉取指定数量群聊天。当有成员发送后会将聊天信息存储数据库(没有缓存进redis,因为在线用户会直接发送,目前没有这个优化必要),从redis中检索所有群组在线用户并通过消息队列发送至对应网关。大致代码如下://处理群消息funcDealGroupMsg(delivery*amqp.Delivery,transfer1*transfer)

大家好,又见面了,我是你们的朋友全栈君。

聊天负责私人聊天,群组聊天。私人聊天接受信息后保存至数据库再转发给目标用户。群组聊天当前没有离线消息保存,也就是用户登录后无法知道多少消息未读,而是直接拉取指定数量群聊天。当有成员发送后会将聊天信息存储数据库(没有缓存进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))
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124739.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号