原来的im 协议:
package com.nami.basic.packet;
import lombok.Data;
import java.io.Serializable;
/**
* 描述:
*
* @Author: lbc
* @Date: 2023-07-14 13:22
* @email: 594599620@qq.com
* @Description: keep coding
*/
@Data
public class Packet implements Serializable {
private static final long serialVersionUID = -9325988132503202L;
// 魔数 (1字节)
private byte magic;
/**
* 消息操作指令(4字节)
*/
private int cmd;
/**
* 1字节 版本号
*/
private byte version;
/**
* 数据解析类型(1字节)
* 子包加密算法
*/
private byte encrypt;
/**
* 1字节 序列化算法
* 子包序列化选择
*/
private byte serial;
/**
* 4字节 包体长度
*/
private int length;
/**
* 业务
*/
private byte[] body;
/**
* 获取包数据长度
*
* @return
*/
public int getLength() {
if (null == body) {
return 0;
}
return body.length;
}
}
问题:
长连接服务启动后,会因为业务变更会再次重启,与业务逻辑有耦合。目标是:长连接服务一次启动,能够长时间不重启
1. 融云相关js sdk设计,融云v2版本链接:最新的v5版本好像没有放在github了
2.为了让长连接服务与业务解耦,设计为:
第一层协议:
magic+version+cmd+qos+body
cmd类似为mqtt枚举,融云的枚举为:
export enum Type {
CONNECT = 1,
CONNACK = 2,
PUBLISH = 3,
PUBACK = 4,
QUERY = 5,
QUERYACK = 6,
QUERYCON = 7,
SUBSCRIBE = 8,
SUBACK = 9,
UNSUBSCRIBE = 10,
UNSUBACK = 11,
PINGREQ = 12,
PINGRESP = 13,
DISCONNECT = 14
}
第二层协议:
topic+targetId+timestamp+body
第一层协议的body就是第二层内容,将第一层body解析出来,通过topic 分发到具体业务服务
第三层协议:
第二层协议的body: 业务逻辑
通过三层协议,解耦。长连接服务可以做到启动一次,不用再次重启,但是需要添加一个协议层,去消费长连接服务发送的mq消息 消息topic为固定字符串前缀+cmd,协议层消费netty服务的消息,去解析topic, 然后再次发送mq消息分发到具体业务逻辑。
注:
是否可以将cmd 直接设置为字符串,变为topic呢?变成两层协议,一层netty解析出来,通过cmd的字符串topic直接分发到业务逻辑
附packetV2版本:
package com.nami.im.network.model.packet;
import lombok.Data;
import java.io.Serializable;
/**
* 描述:
*
* @Author: lbc
* @Date: 2023-07-14 13:22
* @email: 594599620@qq.com
* @Description: keep coding
*/
@Data
public class PacketV2 implements Serializable {
private static final long serialVersionUID = -9325988132503202L;
private byte magic;
private byte version;
private byte cmd;
/**
* mqtt 为三个级别
* qos = 0
* qos = 1
* qos = 2
*
* #没有重试
* qos = 0
* #有重试,且多次
* qos = 1
*
*/
private byte qos;
/**
* 4字节 包体长度
*/
private int length;
/**
* 业务
*/
private byte[] body;
/**
* 获取包数据长度
*
* @return
*/
public int getLength() {
if (null == body) {
return 0;
}
return body.length;
}
}