简易聊天系统-聊天服务

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


相关推荐

  • 波特尔暗空分类法_光辉战机和歼10c对比

    波特尔暗空分类法_光辉战机和歼10c对比传说中的暗之连锁被人们称为 Dark。Dark 是人类内心的黑暗的产物,古今中外的勇者们都试图打倒它。经过研究,你发现 Dark 呈现无向图的结构,图中有 N 个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark 有 N–1 条主要边,并且 Dark 的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark 还有 M 条附加边。你的任务是把 Dark 斩为不连通的两部分。一开始 Dark 的附加边都处于无敌状态,你只能选择一条主要边切断。一旦你切断了一条主要边,Dark

  • MyEclipse10激活成功教程_Myeclipse

    MyEclipse10激活成功教程_Myeclipse一.Myeclipse10下载与激活成功教程Genuitec公司发布了MyEclipse10,一款Genuitec旗下的商业化Eclipse集成开发工具的升级版本。MyEclipse10基于EclipseIndigo构建,为Java和JavaEE项目提供了Maven3的支持。本次发布的版本中还加入了对JaveEE6、HTML5、JPA2和JSF2的支持。版本号10是为了庆祝即

  • 女生学Java好找工作吗?女生适合编程吗?[通俗易懂]

    女生学Java好找工作吗?女生适合编程吗?[通俗易懂]大部分人对于Java程序员都有一个既定印象,那就是程序员都是男生。女程序员可以说是“稀有物种”,因为Java工作对于逻辑的要求很高,而这方面男生相对于女生比较有优势。但所有事情都不是绝对的,现在女生从事程序员工作的也越来越多,在某些方面相对于男生也有优势。今天,IT培训机构的小编就来给大家分析分析,女生学Java好找工作吗?女生适合编程吗?市场上现在对Java人才的需求明显是供不应求,Java薪资一哭看涨,企业需要Java人才。Java在生活中运用到各个领域,就业方向选择很宽广。女生选择学Java既有钱

  • 数据库建表语句的使用及简单实战教程_SQL数据库建立一个表

    数据库建表语句的使用及简单实战教程_SQL数据库建立一个表目录介绍需求思路思路1:一张表来表示所有数据(如下图)思路2:两张表,学生表和班级表(如下图)代码扩展1.数据库设计三范式1.数据库表中不能出现重复记录,每个字段是原子性的不能再分(不可重复,不可再分)2.第二范式是建立在第一范式基础上的,另外要求所有非主键字段完全依赖主键,不能产生部分依赖3.建立在第二范式基础上的,非主键字段不能传递依赖于主键字段。(不要产生传递依赖)2.经典的数据库设计框架–er图介绍本文将用一个简单的tip来简单介绍建表语句,可以作为建表语句的模板使用需求采集一个学校中学生

  • Google搜索引擎的使用技巧「建议收藏」

    Google搜索引擎的使用技巧「建议收藏」Google搜索引擎的使用技巧(大家共同学习)1.全文搜索由于google搜索引擎默认空格是加号的规则:例如:mysqlforeignkey能搜索到mysql或者mysqlforeign但不一定能搜索得到mysqlforeignkey,如果要能搜索到mysqlforeignkey就要这样子“mysqlforeignkey”2.模糊搜索例如

  • PLSQL操作Oracle创建用户和表

    PLSQL操作Oracle创建用户和表1、打开PLSQL,填写用户名和密码(初始有两个用户sys和system,密码是自己安装oracle数据库时定的),Database选择ORCL(默认数据库,oracle中创建的用户就像是mysql中建的数据库,两者有异曲同工之妙)2、登陆成功后在界面的头部可以看到一下信息,最上面的system@ORCL就表示是用户system在登录状态,其中菜单栏的session可以登录、退出…

发表回复

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

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