zoukankan      html  css  js  c++  java
  • 基于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协议

  • 相关阅读:
    [国家集训队]墨墨的等式(同余最短路)
    [洛谷P2575]高手过招
    [CSP校内集训]rank
    杀人游戏(tarjan思维好题)
    骑士游戏(spfa好题)
    机房模拟测试4:计数类dp+水题+树上计数
    机房测试模拟2:模拟+数学+数位dp
    机房测试11:最小生成树(最小生成树+二分)
    机房测试模拟1(day2):矩阵+树上贪心+bfs+状压
    机房测试16:字符串专题(AC自动机+dp+kmp)
  • 原文地址:https://www.cnblogs.com/venny/p/3796825.html
Copyright © 2011-2022 走看看