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协议

  • 相关阅读:
    Civil 3D 二次开发 创建Civil 3D 对象—— 01 —— 创建几何空间点
    Civil 3D 二次开发 创建Civil 3D 对象—— 00 ——
    Civil 3D 二次开发 创建AutoCAD对象—— 01 —— 创建直线
    Civil 3D 二次开发 新建CLR项目出现错误C2143
    Civil 3D 二次开发 创建AutoCAD对象—— 00 ——
    了解AutoCAD对象层次结构 —— 6 ——块表记录
    datepicker97使用
    使用angular 外接 templateUrl,使用ng-include
    angularJs 遮罩
    网上找的有关css兼容问题
  • 原文地址:https://www.cnblogs.com/venny/p/3796825.html
Copyright © 2011-2022 走看看