欢迎阅读我的开源项目《迷你微信》服务器)与《迷你微信》客户端

前言

在上一篇中,我们讲到了《迷你微信》服务器)的主体架构,还讲到了如何在现有功能上进行拓展,但是拓展的其中一个关键点,就是如何区分客户端的请求类型(如:登陆?注册?)?我们将通过对传输协议的制定标志位进行检测来确定客户端的请求类型,在本项目中,我们使用Protobuf来定义传输协议而已,若是您对于Protobuf还不甚了解,可以先学习下【迷你微信】基于MINA、Hibernatye、Spring、Protobuf的即时聊天系统:6.技术简介之Protobuf

协议的定义

在[《迷你微信》服务器][1]中,服务器和客户端所定义的协议为:

  • 1.Size:类型为int,转化为byte数组后占4个字节。
  • 2.ProtoHead:消息类型(如:登陆?注册?)类型为ProtoHead,转化为byte数组后占4个字节。
  • 3.MessageId:一次消息的Id,类型为float,转化为byte数组后占4个字节。
  • 4.MessageBody:消息主体,类型根据ProtoHead 参数 使用 Protobuf 进行转化,占用的字节数为 size - sizeOf(size) - sizeOf(ProtoHead) - sizeOf(MessageId),也就是size 转化为int后的数值减去4 * 3。

注:上述的”消息“指的是客户端的一次请求或服务器的一次回复或服务器对客户端的一次推送。

在每一次服务器与客户端的交流中,都必须遵守这样的一个协议,否则可能会出现难以估量的异常状态。可能您会产生怀疑,若是数据包在传输的过程中丢了一个包,或者收到数据包的前后顺序乱了,会发生什么事?其实,我们用的是TCP的协议,TCP协议是会对数据包进行排序和检验丢包的,详细的介绍可以参考【迷你微信】基于MINA、Hibernatye、Spring、Protobuf的即时聊天系统 :1.技术简介之Mina连接

ProtoHead

前面说了,从第五到低8个字节,是ProtoHead,类型也叫ProtoHead,拿这个ProtoHead是什么东西呢?

ProtoHead是使用Protohead编写的其中一个协议,若是您需要对Protobuf进行了解,请参考【迷你微信】基于MINA、Hibernatye、Spring、Protobuf的即时聊天系统:6.技术简介之Protobuf

我们先来看看ProtoHead的定义:

package protocol;

option java_package = "protocol";

enum ENetworkMessage{
KEEP_ALIVE_SYNC=0;
REGISTER_REQ=1;
REGISTER_RSP=2;
LOGIN_REQ=3;
// 后面还有很多,就不进行展示了。
}

先解释一下:

  • KEEP_ALIVE_SYNC : 心跳包类型,服务器向客户端发送心跳包以保证对方在线。
  • REGISTER_REQ : 注册请求类型,这是客户端向服务器发送的注册新账号的请求。
  • REGISTER_RSP : 注册回复类型,服务器在处理完客户端的注册请求后,向客户端回复结果。
  • LOGIN_REQ : 登陆请求类型,这是客户端向服务器发送的登陆账号的请求。

大家可以发现,其实这只是一个枚举而已,网络传输的时候,我们可以将其转化为int类型再转为四个字节。

到此,想必大家已经明白了上一章节中如何区分客户端请求的类型了,在ClientRequest_Disptcher类中,根据ProtoHead的值,就可以区分出客户端请求的类型。如果要添加新的功能(服务器与客户端的交互),则需要在ProtoHead中加入一个新的枚举类型。

设计新功能

那么如何设计一个新功能的Protobuf呢?

  • 设计新的客户端与服务器交流的Protobuf 。
  • 在ProtoHead中加入新功能的类型。

现在,加入我们有个功能,是要获取某个人的详细信息,那么Protobuf 文件 GetUserInfoMsg.proto 将如此设计:

package protocol;

option java_package = "protocol.Msg";
import "UserData.proto"; message GetUserInfoReq{
repeated string targetUserId = 1 ;
} message GetUserInfoRsp{
enum ResultCode{
SUCCESS = 0;//搜索到用户
FAIL = 1;//未搜索到用户
USER_NOT_EXIST = 2;//用户不存在
}
required ResultCode resultCode = 1;
repeated UserItem userItem = 2;
}

大家可以发现,在这里面有两个消息,一个是客户端发出的”获取用户信息请求“(GetUserInfoReq ),一个是”回复获取用户信息请求“(GetUserInfoRsp ),在GetUserInfoReq 中,只有一个参数:目标用户的Id。而在GetUserInfoRsp 中,首先有一个枚举的结果,代表获取信息的结果:搜索到用户、未搜索到用户和用户不存在,接着,是一个UserItem对象,为什么不是详细数据,而是一个UserItem对象呢?因为UserItem这个对象在很多地方都是要用到的,比如,在”群聊人员表“ 可能是由多个UserItem组成,为了减少重复代码,所以将其设计成了单独的一个UserItem。

在此再次强调:消息名不能与文件名相同!

接着,可以在ProtoHead文件中加入新功能的类型枚举了:

	GET_USERINFO_REQ=7;
GET_USERINFO_RSP=8;

从此,在客户端向服务器发送的”获取用户信息请求“数据包时,需要将ProtoHead位置设为 GET_USERINFO_REQ ,在服务器回复客户端结果时要将ProtoHead位置设为 GET_USERINFO_RSP 。

后话

在下一章节,帖主将为大家介绍一下项目内的一些类的详细设计。

欢迎阅读我的开源项目《迷你微信》服务器)与《迷你微信》客户端

【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:8.自定义传输协议的更多相关文章

  1. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:0.概述

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 序言 帖主和队友仿制了一个简单版的微信,其中,队友是用Unity3D做前段,帖主用Java的Mina.Hiberna ...

  2. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:7.项目介绍之架构(1)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 <迷你微信>服务器端是使用Java语言,Mina框架编写的,一个良好的架构关系到后期迭代的方便程度 ...

  3. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:9.观察者模式

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 在一个程序的迭代过程中,复杂度渐渐上升,可能会出现一些跨模块的调用的需求,若是直接得到引用来进行使用,会导致模 ...

  4. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:6.技术简介之Protobuf

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 protocolbuffer(以下简称Protobuf)是google 的一种数据交换的格式,它独立于语言,独立于平 ...

  5. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:5.技术简介之Hibernate

    目录 序言 配置 hibernate.cfg.xml配置文件 加载hibernate.cfg.html配置文件并获取Session 对象的注解配置 增删改查 具体的增删改查代码 数据库操作的封装 连接 ...

  6. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统 :1.技术简介之Mina连接

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Apache MINA(Multipurpose Infrastructure for Network Applic ...

  7. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:4.技术简介之Spring

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Spring是一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One ...

  8. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:3.技术简介之MinaFilter——LoggingFilter (转)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 LoggingFilter 接下来,使我们对Filter介绍的最后一个——LoggingFilter. 与Proto ...

  9. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:10.项目介绍之架构(2)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 前面我们讲到<迷你微信>服务器端的主架构,现在我们来描述一下它的模块详细信息. 网络模块 从上图我 ...

随机推荐

  1. storm源码分析之topology提交过程

    storm集群上运行的是一个个topology,一个topology是spouts和bolts组成的图.当我们开发完topology程序后将其打成jar包,然后在shell中执行storm jar x ...

  2. jQuery学习1

    学习jQuery的过程中发现了一个博客把jquery的要点整理的很不错,摘抄其精华以备学习.感谢:http://blog.csdn.net/wph_1129/article/details/59932 ...

  3. C++ STL 的各结构实现

    C++ STL 的实现: 1.vector  底层数据结构为数组 ,支持快速随机访问 2.list    底层数据结构为双向链表,支持快速增删 3.deque   底层数据结构为一个中央控制器和多个缓 ...

  4. 在虚拟机环境(CentOS7系统)下将kubernetes中部署服务成功,但在虚拟机外部无法访问到服务

    在CentOS7环境下,kubernetes单机版环境,成功部署一个服务,在虚拟机中访问服务没问题,下面这样: curl http://172.27.73.26:8888/eureka-server/ ...

  5. kolla-build常用命令行详解

    --base-image 用于指定使用自己定制的基础镜像,不用官方网站的样例如下:kolla-build --base-image registry.access.redhat.com/rhel7/r ...

  6. c++第五次实验

    part 1 两个问题: 1.派生类中出现与基类同名成员,通过对象名.成员名的方式,即代码中base2.display(),访问的成员是派生类中的成员 2.通过基类指针访问派生类对象时,在ex1_1. ...

  7. 为什么MOBA和吃鸡类游戏不推荐用tcp协议 延迟不利于实时游戏

    http://news.gamedog.cn/a/20171221/2287418.html 我们知道,不同类型的游戏因为玩法.竞技程度不一样,采用的同步算法不一样,对网络延迟的要求也不一样.例如,M ...

  8. poj3694(lca + tarjan求桥模板)

    题目链接: http://poj.org/problem?id=3694 题意: 给出一个 n 个节点 m 条边的图, 然后有 q 组形如 x, y 的询问, 在前面的基础上连接边 x, y, 输出当 ...

  9. [Xcode 实际操作]四、常用控件-(15)MKMapView加载简单视图

    目录:[Swift]Xcode实际操作 本文将演示地图视图的使用方法. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //首先往视图控制 ...

  10. angularJs中对时间戳的处理

    一. ng表达式 <!-- 表达式中使用 --> {{ dt1 | date:'yyyy-MM-dd HH:mm:ss' }} 二. 控制器中使用 //controller必须注入 $fi ...