TeamTalk消息协议

teamtalk实现即时通讯 即时通讯技术应用非常广泛,涉及教育、电商、金融、泛娱乐、生活服务、医疗健康、政企服务、游戏聊天、在线客服等等行业,不是大家认为仅仅是qq、微信那样。 即时通讯架构 先给张图 客户端与服务器端进行网络通信、收发消息连接层为客户端收发消息提供出入口。主要的任务:保持海量用户连接;解析协议,对传输内容进行编码;维护session;推送消息。 核心业务层负责IM系统各项功能的核心逻辑实现。 数据层负责IM系统相关数据的持久化存储,包括消息内容、账号信息等。 分层架构 接入层的作用:连接整流、通信安全、报文解压缩 阅读详情

数据通讯格式封装协议 Protocol Buffer

常用序列化方案比较 参考 

https://www.cnblogs.com/johnny666888/p/12841735.html

Protocol Buffer 

Protocol Buffer还有一个非常重要的优点就是可以保证同一消息报文新旧版本之间的兼容性
 

protobuf协议核心思想

基于128bits的数值存储方式(Base 128 Varints)

数据表示方式:每块数据由接连的若干个字节表示(小的数据用1个字节就可以表示),每个字节最高位标识本块数据是否结束(1:未结束,0:结束),低7位表示数据内容。(可以看出数据封包后体积至少增大14.2%)

数字1的表示方法为:0000 0001,这个容易理解

数字300的表示方法为:1010 1100 0000 0010

protobuf字节序是小端字节序,所以这个数字实际是0000 0010 1010 1100

1010 1100 0000 0010

→ 010 1100 000 0010

如下:

000 0010 010 1100

→ 000 0010 ++ 010 1100

→ 10 0101100

→ 256 + 32 + 8 + 4 = 300

基于序号的协议字段映射(类似key-value结构)

所以字段可以乱序,可缺段(记optional)

message person{

required string name = 1;

required string country = 2;

optional int32 age = 3;

}

效果相当于json数据:person= [{1: "john"}, {2: "USA"}, {3: 30}],其中{3: 30} 还可以不传,person还可以传成 [{2: "USA"}, {1: "john"}],对端仍旧可以正常解析。

基于无符号数的带符号数表示(ZigZag 编码)

原始的带符号数ZigZag编码后的表示
00
-11
12
-23
21474836474294967294
-21474836484294967295

使用 zigzag 编码,充分利用基于128bits的数值存储(Base 128 Varints)的 技术,只需要加多1个位来表示符号。当绝对值小的数字非常有利,这种方式可以有效减少协议内容长度。

sint32类型编码如下:

(n << 1) ^ (n >> 31)

sint64类型编码如下:

(n << 1) ^ (n >> 63)

协议数据结构

protobuf怎么在一长串二进制中表示若干个数据?

做法就是每块数据前加一个数据头,表示数据类型及协议字段序号。

msg1_head + msg1 + msg2_head + msg2 + ...

数据头也是基于128bits的数值存储方式,一般1个字节就可以表示:

message Test1 {

required int32 a =1;

}

如上创建了 Test1 的结构并且把 a 设为 2,序列化好的二进制数据为:

0 000 1000 0 000 0010

以上数据转成十六进制也就是 08 02,其中 8 是怎么得到的?

000 1 000

低3位表示数据类型:0,其他表示协议字段序号:1,加上最高位0, 结果就是8

数据类型的表示如下:

类型含义用于哪些数据类型
0Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages, packed repeated fields
3Start groupgroups (deprecated)
4End groupgroups (deprecated)
532-bitfixed32, sfixed32, float

 TeamTalk proto

  pb目录下 定义了消息

基础数据结构的定义在IM.BaseDefine.proto中。

见 IM doc文件下协议说明 

消息数据流;

如获取部门列表

buildProtoMsg ====>

//封装数据 SID CID
IMBuddy.IMDepartmentReq imDepartmentReq  = IMBuddy.IMDepartmentReq.newBuilder()
        .setUserId(userId)
        .setLatestUpdateTime(lastUpdateTime).build();
int sid = IMBaseDefine.ServiceID.SID_BUDDY_LIST_VALUE;
int cid = IMBaseDefine.BuddyListCmdID.CID_BUDDY_LIST_DEPARTMENT_REQUEST_VALUE;

 //组装包头 header
            com.mogujie.tt.protobuf.base.Header header = new DefaultHeader(sid, cid);
            int bodySize = requset.getSerializedSize();
            header.setLength(SysConstant.PROTOCOL_HEADER_LENGTH + bodySize);
            seqNo = header.getSeqnum();
            listenerQueue.push(seqNo,packetlistener);
            boolean sendRes = msgServerThread.sendRequest(requset,header);
//写入buffer
  DataBuffer headerBuffer = header.encode();
        DataBuffer bodyBuffer = new DataBuffer();
        int bodySize = requset.getSerializedSize();
        bodyBuffer.writeBytes(requset.toByteArray());


        DataBuffer buffer = new DataBuffer(SysConstant.PROTOCOL_HEADER_LENGTH  + bodySize);
        buffer.writeDataBuffer(headerBuffer);
        buffer.writeDataBuffer(bodyBuffer);

        if (null != buffer && null != channelFuture.getChannel()) {
          
            Channel currentChannel =  channelFuture.getChannel();
            boolean isW = currentChannel.isWritable();
            boolean isC  = currentChannel.isConnected();
            if(!(isW && isC)){
                throw  new RuntimeException("#sendRequest#channel is close!");
            }
//socket 发送
            channelFuture.getChannel().write(buffer.getOrignalBuffer());

IM-server接收端

MsgConn.cpp  

_HandleClientDepartmentRequest 处理

void CMsgConn::HandlePdu(CImPdu* pPdu)
{
	// request authorization check
	if (pPdu->GetCommandId() != CID_LOGIN_REQ_USERLOGIN && !IsOpen() && IsKickOff()) {
		log("HandlePdu, wrong msg. ");
		throw CPduException(pPdu->GetServiceId(), pPdu->GetCommandId(), ERROR_CODE_WRONG_SERVICE_ID, "HandlePdu error, user not login. ");
		return;
	}
	switch (pPdu->GetCommandId()) {
		case CID_OTHER_HEARTBEAT:
			_HandleHeartBeat(pPdu);
			break;
		
		//....

		case CID_BUDDY_LIST_USERS_STATUS_REQUEST:
			_HandleClientUsersStatusRequest(pPdu);
			break;
		case CID_BUDDY_LIST_DEPARTMENT_REQUEST:
			_HandleClientDepartmentRequest(pPdu);
			break;
			// for group process
		case CID_GROUP_NORMAL_LIST_REQUEST:
			s_group_chat->HandleClientGroupNormalRequest(pPdu, this);
			break;
		case CID_GROUP_INFO_REQUEST:
			s_group_chat->HandleClientGroupInfoRequest(pPdu, this);
			break;
		case CID_GROUP_CREATE_REQUEST:
			s_group_chat->HandleClientGroupCreateRequest(pPdu, this);
			break;
		case CID_GROUP_CHANGE_MEMBER_REQUEST:
			s_group_chat->HandleClientGroupChangeMemberRequest(pPdu, this);
			break;

	
		//....

		default:
			log("wrong msg, cmd id=%d, user id=%u. ", pPdu->GetCommandId(), GetUserId());
			break;
	}
}
void CMsgConn::_HandleClientDepartmentRequest(CImPdu *pPdu)
{
    //消息检查 时间戳对比数据变更 
	IM::Buddy::IMDepartmentReq msg;
	CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
	log("HandleClientDepartmentRequest, user_id=%u, latest_update_time=%u.", GetUserId(), msg.latest_update_time());
     //数据库
	CDBServConn* pDBConn = get_db_serv_conn();
	if (pDBConn) {
		CDbAttachData attach(ATTACH_TYPE_HANDLE, m_handle, 0);
		msg.set_user_id(GetUserId());
		msg.set_attach_data(attach.GetBuffer(), attach.GetLength());
		pPdu->SetPBMsg(&msg);
		pDBConn->SendPdu(pPdu);
	}
}


//关键类
//class CDBServConn : public CImPduConn

协议扩展 

根据需要修改

BaseDefine.proto等 协议文件  增加相应的业务类型指令 KEY 同时修改server接收端处理业务逻辑 client 修改对应反序列化代码即可

蘑菇街TeamTalk跨平台即时通讯项目源码实战 TeamTalk采用典型的分布式即时通信架构,整体分为客户端、接入层、服务端集群与数据存储四大层次。客户端涵盖Android、iOS及桌面平台,通过TCP长连接与服务端MsgServer保持通信;服务端模块化设计,包含LoginServer、MsgServer、DBProxy等独立组件,借助ZooKeeper实现服务发现与配置同步,支持横向扩展与高可用部署。 阅读详情

相关推荐

TeamTalk Windows客户端程序执行与编译解析

本文还有配套的精品资源,点击获取 简介:TeamTalk是一个面向团队协作的多用户即时通讯软件,提供音视频通话、文字聊天和文件传输等功能。Windows客户端是实现远程协作的核心,负责将源代码编译成可执行文件.exe。客户端开发涉及到网络编程、音视频编解码技术、用户界面设计、文件传输机制等关键技术点,同时考虑了安全性和稳定性,采用了加密技术如SSL/TLS协议。此程序的执行...

weixin_42561464的博客 1100

网络通信(Telematik)-传输层协议(Transportprotokoll)2

网络阻塞(Stau im Internet)网路中传输的数据包过多,导致超出网路的承受能力。简单的队列管理Router: 当router的Puffer满了,那么下一个到达的数据包将被直接扔掉 发送者(Sendeinstanz): 设置重传计数器(Retransmission Timer),当时间到了则从新发送数据包 问题:同步 大量不同TCP连接的数据包会几乎同时被扔了积极的队列管理基本措

Teufel_Huang的博客 1013

自己实现的protobuf 压缩类,并能序列化反序列化

自己实现的protobuf 压缩类,并能序列化反序列化

Teamalk在服务端新增协议

转自:www.bluefoxah.org/teamtalk/add_protocol.html 1、如何增加一个协议 很多人问我如何增加一个处理协议,我先大致讲下整个过程,在后面针对每一步进行详细的讲解,本次就以群里一个群友问得如何增加修改密码的协议为例。 因为新版TT是基于PB处理的,所以, 1、我们要在pb文件中增加相应的命令号,协议定义。 2、重新生成协议文件。 3、在服

mao834099514的博客 1253

yolov5部署之七步完成tensorRT模型推理加速

目录前言step 1. 下载yolov5源码以及tensorrtx源码,并将yolov5s.pt转为.wts模型step 2. 确定并下载自己准备使用的CUDA版本。step 3. 根据自己的CUDA版本下载对应版本的cuDNN以及TensorRTstep 4. 根据自己使用的VS版本下载对应版本的OpenCVstep 5. 安装CUDAstep 6. 安装cuDNN、TensorRT以及验证TensorRT是否安装成功 前言     前段时间研究了Pytorch的环境配置,之后便从github上下载了yo

Christo的博客 4万+

波分复用-Zblock仿真

Z-BLOCK是一种用于光通信模块的光学元件,其核心结构是在玻璃块一侧贴有4个特定波长滤光片,另一侧镀有反射膜和增透膜。光信号在内部呈现Z字形反射路径,实现波长分离。文章以可见光LED为例,在ZEMAX中演示了非序列模式下的建模过程,重点介绍了滤光片和膜层的参数设置方法。需要注意的是,入射角度需根据玻璃折射率、通道高度和厚度精确计算,否则可能导致光泄漏。该建模方法同样适用于光通信中的光纤激光器系统。

Zhaxibamao的博客 1749

Protobuf原理

Protobuf原理

Wite_Chen 5415

100天精通Python(可视化篇)——第109天:Pyecharts绘制各种常用地图(参数说明+代码实战)

100天精通Python(可视化篇)——第109天:Pyecharts绘制各种常用地图(参数说明+代码实战)

努力让自己发光,对的人才能迎着光而来 8万+

protobuf实现Hbase数据压缩

每次写入数据会写入4个单元格的内容,现在希望能对其进行筛减,合并成1格,减少存储空间(序列化)此处仅修改了插入方法之前的内容,将数据合并,对于插入方法没有做修改,其他内容仿照之前的即可。导入myPhone.java——protobuf生成的java文件。修改pom.xml——增加对protobuf的依赖。数据存储格式已经修改,因此获取数据的方式需要改变。编写HbaseDML.java(参考专栏博客)在上文的datain中。

wusuoweiieq的博客 802

[Dify实战] 解决 Dify 导入 DSL 文件时报 “DSL 版本差异” 的兼容性问题

摘要:本文针对Dify开发者在导入.dsl文件时遇到的版本警告提示问题,分析其根源在于DSL文件与当前系统版本不一致。解决方案是通过导出当前Dify应用的DSL文件查看版本号,手动修改待导入文件的version字段以匹配。文章详细说明了操作步骤,并给出使用专业编辑器、避免修改其他字段等实用建议,帮助开发者规避版本不兼容问题,提升多模态AI应用开发效率。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 961

论文深度解析:基于大语言模型的城市公园多维度感知解码与公平性提升

本文针对城市公园感知测量的精细化不足与公平性评估缺口,提出了一套融合社交媒体数据与大语言模型(LLM)的创新分析框架。通过领域适配微调开发的Park-Perception-LLM模型,实现了对感知可达性、可用性、吸引力三大核心维度83%-91%的高精度分类。将该感知指标创新性地融入增强两步浮动集水区法(E2SFCA),以香港高密度城市为案例,系统揭示了公园质量与数量的空间不平等及错配模式。借助多元回归模型,深入挖掘了公园内部特征、宏观建成环境、微观街道景观及时间因素对感知的影响机制。

May the Force be with you 1014

TeamTalk中msg_server初始化工作,如何维护与其他服务器的心跳连接

msg_server首次启动需要做什么,学习服务器之间的心跳包设计以及重连机制

QNBZ的博客 418

PyQt5开发编译器安装(PyCharm安装)

PyCharm 提供了最完整的 PyQt5 开发体验,特别是其集成的调试工具和 Qt Designer 支持,能显著提高开发效率。是最受欢迎和功能最完整的 IDE。它专门为 Python 开发优化,对 PyQt5 有很好的支持。右键运行该文件,如果出现窗口说明配置成功。对于 PyQt5 开发,

啊渊的专栏 419

TeamTalk消息服务器(群组相关)

后调用 DB_PROXY::getNormalGroupList 函数。db_proxy_server 收到。

COOL_jack的博客 681

基于matlab的CNN手写数字图像矫正系统

CNN 是一款强大的图像特征抽象和提取工具,常用于图像分类识别,并取得了较为理想的效果。我们通过 MATLAB 可以方便地设计不同结构、不同深度的 CNN 进行图像分类,最后一层一般设置为分类层(ClassificationLayer)进行类别标签的输出。如果我们将最后一层设计为回归层(RegressionLayer),则可以将其应用于对连续数据的预测,这对于曲线拟合、预测分析都有重要的意义。% 自定义 CNN 回归网络结构layers = [% 输入% 卷积% 池化% 池化% 卷积。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 676

Spring Boot:如何快速搭建一个高性能微服务架构?

通过本文的详细步骤,我们成功搭建了一个高性能的微服务架构。Spring Boot 和 Spring Cloud 提供了强大的工具链,使得开发者能够快速实现服务注册与发现、负载均衡、熔断器与降级机制等功能。同时,通过数据库连接池、Redis 缓存和异步处理等优化手段,进一步提升了系统的性能和可靠性。希望本文能够帮助你快速入门 Spring Boot 微服务架构的搭建,并为实际项目提供参考。如果你有任何问题或建议,欢迎在评论区留言!

shrgegrb的博客 1013

TeamTalk消息服务器(未读计数)

TeamTalk 消息未读计数设计初步分析

COOL_jack的博客 826

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

teamtalk原理

再贴一遍架构图 从图中可以看出,对外使用的是http连接,内部使用的是tcp长连接。 类的命名规则:xxxServConn是模块连别的模块,xxxConn是别的模块连它。 协议设计 teamtalk采用protobuf进行序列化 typedef struct { uint32_t length; // the whole pdu length uint16_t version; // pdu version number uint16_t flag; // no

m0_65931372的博客 2153

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

心跳保活---TeamTalk心跳保活机制分析

由于蘑菇街的TeamServer包含了login_server ,msg_server等几个不同的服务端,本文会逐步进行分析,并持续更新。。。。。 首先分析为什么需要应用层的心跳机制 对应IM使用TCP协议还是UDP协议还是个有争议的话题,仁者见仁智者见智,不过个人觉得这得看实际应用场景,根据应用场景的不同用不同的协议。在TCP协议实现的IM中,需要考虑一个很重要的问题就是心跳保活,那么什么是

u010485442的专栏 630

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

基于Spring Cloud和Netty的聊天系统——sctalk项目推荐

基于Spring Cloud和Netty的聊天系统——sctalk项目推荐 1. 项目基础介绍 sctalk 是一个开源的聊天系统项目,基于 Spring Cloud 和 Netty 技术栈进行开发。项目完全用 Java 生态重构而成,兼容蘑菇街 TeamTalk 客户端,旨在为线上业务提供稳定的聊天服务。项目采用了分布式架构,通过 Hazelcast 提供消息服务器集群功能,同时支持 Socke...

gitblog_00203的博客 730

TeamTalk 服务器代码分析

转自https://blog.youkuaiyun.com/hailong0715/article/details/52804165 本文主要分析TeamTalk的服务器架构中MsgServer的启动流程,在TeamTalk的各个服务器中,消息服务器Msg-Server是最复杂。本文剖析了其启动流程。 1、在Msg_server.cpp的main函数是消息服务器启动的入口函数,其主要的流程包含一下几个部分: (1)、读取配置文件中设置的各个服务器的监听IP和端口。 (2)、初始化网络库 (3)、消息服务器在监

cc13949459188的博客 421

IM即时通讯项目框架分析

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习 1 IM即时通讯项目框架分析和部署 1. 即时通讯框架分析和部署 2. 登录服务器和消息服务器设计 3. 路由服务器设计 4. 数据库代理服务器设计 5. 文件服务器和docker部署 6. 性能测试和k8s上云发布 1.1 即时通讯应用场景 即时通讯

qq_46118239的博客 7665

TeamTalk整体梳理

答:A发送消息给客户端B,msg_server收到后,直接将数据包转发db_proxy_server,db_proxy_server有一个map来映射信令所对应的处理函数。msg_server连上login_server后会立刻给login_server发一个数据包,该数据包里面含有该msg_server上的用户数量、最大可容纳的用户数量、自己的ip地址和端口号。多个msg_server和db_proxy_server建立连接时,会将每个proxyconn连接和m_uuid一一对应映射起来。

COOL_jack的博客 1261

浅谈teamtalk

蘑菇街开源的teamtalk可以作为2-3年初学者学习之用,或者小型公司当作内部im办公交流之用。至于源码讲解,网上开源的挺多。迷茫且闲着没事的初学者们可以简单看看,看网络框架大概一天可以看明白,看业务,大概需要一到两周,需要去centos7.0以上部署下,msgserver可以看完代码配置2个试试,调试。客户端代码也可以简单看看。还是有一定价值的,像网络框架通用,简单,没有过多炫技...

huosiren44的博客 1063

TeamTalk源码分析——群聊技术方案和群未读计数的实现

群聊分析 app发送群消息到msg_server msg_server收到后,以本地时间戳设置消息创建时间(客户端时间不可靠) 转发 向数据库查询群ID有效性,非法则直接忽略 该成员是否在群成员内,非法则直接忽略 用户和群的会话是否存在,不存在自动创建一条会话关系 生成群内唯一消息ID 写入数据库表group_msg中(按照gruopId%8分表) 返回ack 返回ack(如果有多端登录,广播msg到多个端,各个端再回复ack确认) 向db_proxy_server查询群成员列表 查数据库 接收群成员

xmcy001122的专栏 1678

teamtalk简介

置顶:关于用smart pointer修改的demo源码我放在了我的开源中国的git目录下, 这个地址:http://git.oschina.net/benben-de-eggs/tt-code-fragment 修改基于一个原则,不会动老的接口,也就是说,以前的代码不需要修改成智能指针也一样能编译运行。 文章有点长,而且废话较多,看得不耐烦的同学敬请谅解,本人第一次写博客,有点

lcalqf的专栏 5758
上一篇: Php框架CodeIgniter 学习
下一篇: GDB与shell 调试
江太翁
博客等级 码龄15年 271粉丝 141原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值