首页 > 代码库 > 基于Netty的聊天系统(三)协议定制----消息篇

基于Netty的聊天系统(三)协议定制----消息篇

今天我们继续来讨论协议,今天基本就把一对一聊天的协议定制完毕了,上一篇我们讲述了登录的过程,那么登录完毕就是聊天了,首先我们还是以A和B为例子,A发送消息给B,那么这条消息的的协议如下

发送消息协议:

 

{"id":"xxxx","#":"msg","text":"内容","to":"接收用户ID","type":0,"msgid":"消息ID"

id:客户端生成的ID

#:不说了,我们之前说过,是对应服务器端的Handler

text:消息内容

to:表示发送给谁

type:表示消息类型

msgid:表示消息的ID

肯定有很多人之后看到之后会有一个问题,我们到底需不需要from 也就是说发送者是谁,其实在这里加上也行,但是其实是不需要的,因为如果既然这个人可以发送消息,那么我们可以在这个人对应的回话里边去存储这个人的信息,所以说只要发送消息,服务器就知道这条消息来自谁,故不需要在这里加from,然后服务器端要响应给该用户是否发送成功,返回的协议,我们在上一篇

auth那里讲述了,用同一个就好了,那么现在服务器如果发现B在线该去通知B来收消息了,那么我们看一下服务器通知B的协议

服务器通知B的协议:

{"id":"xxxx","#":"psh"}

id:服务器生成的id

#:我们这里用了一个psh表示,通知该用户你有新的消息,要获取了,那么B解析到#为psh的时候就应该去请求服务器收消息了 psh=push

B请求服务器收消息协议

{"id":"xxxx","#":"msg-syn"}

id:客户端生成ID

#:对应服务器上的某一个Handler

服务器接收到这个json之后,首先会去从回话中找到B的id,然后去redis中查询聊天信息,多加一句,这里我们存储redis的时候,key值是我们自己订制规则添加的,例如如果B的id为1111

那么我定义的key为user:1111:msg,所以获取消息时候要获取B的id

获取完毕之后,那么我们就可以把消息给B了,那么对应的有一个发送消息的协议格式

发送消息协议:

{"id":"xxxx","fr":"发送用户","text":"内容","time":"消息时间","type":0,"msgid":"消息ID""lv","100"}

id:服务器端生成的id

fr:发送用户

text:消息内容

time:消息时间

type:消息类型

msgid:消息id

lv:这个不太好理解,这是消息的最大score值,可能很多人对score值不清楚,怎么无缘无故冒出来一个这个东西,我们来解释一下,比方说A给B发送消息

那么A如果发送了4条消息,对应的存储应该是:
                   score      value
zset结构:        1        msg1
                        2        msg2
                        3        msg3
                        4        msg4
那么如果用户B来取消息的时候,我们会找到该系列消息,发送给B,然后B接受成功后,返回json字符串,该字符串 ,包含的内容有,是否接受成功,以及最大消息的score值,该值的作用是如果B接受消息成功,我们要把这些消息从,redis中删掉,redis提供了一个根据score进行区间删除的方法我们就可以删掉0--MAX之间的所有消息了,如果还不明白可以去了解一下redis,如果后续有时间,会把进行数据存储的代码贴上来,所以说现在知道我们为什么要获取最大的值了把。

那么在给B发送消息的时候我们并没有结束,当把B所有的消息都给B的时候服务器会在最后再发送一条json数据,这里边包含了是否全部消息都已经发送完毕了,等等信息,如果B接受到该条数据的时候就表示全部收取完毕了,好多朋友会感觉到很不解,为什么最后的这条json里边会包含了是否消息发送完毕的内容,这里我们做个假设,如果B的人气非常火,每天有好多好友给他发消息,那么消息数量会很多,所以当B来去消息的时候我们并不会一下子都把消息给B,假设B有1000个消息,我们可能每次就给B100条,然后在这100条后边加上最后的这个json数据,里边告诉B是否消息已经全部收取了,B可以根据自己的选择来选择是继续获取还是不获取了,主要是做这个使用,那么废话不多说,我们来看看该条协议的定制

{"id":"57968203","#":"msg-ack","remain":0,"lv":["msg":2]}

id:服务器端生成的id

#:msg-ack这是结束表示符,表示这一次消息已经发送完毕

remain:表示是否还有剩余消息0表示消息全部发送完毕,1表示还有消息未读

lv:这里边我们放了一个消息的最大值,其实在这里没有什么含义,客户端在返回的时候还是要把这个值返回来的,用数组的原因是后期可能还有很多别的要放在这里边

客户端收到消息时候会响应服务器端的,协议如下

客户端收到消息响应协议:

{"id":"","#" : "msg-fin","lv" : {"msg" : 2}}

id:不说了

#:msg-fin表示获取消息已经结束了,也就是说B不去获取消息了,

lv:和上边是一样的了,如果实在不懂这个暂时可以忽略掉

那么这么以来一个简单的一对一聊天的协议我们制定完毕了,其实还有很多细节我没有去展示,例如心跳机制,还有例如如果B不在线的时候,B如果上线了要主动去获取一下消息,还有就是检测用户是否更换了手机等等细节,这个大体说一下更换手机这方面,更换手机我们依靠的时候用户手机设备信息然后计算出来一个值,每次去和服务器做对比,这个值什么时候给服务器那,其实在登录成功之后,随便找个空闲时间就可以搞定了,也需要定制一个具体的json协议