java接收小程序发送的protobuf消息

1、定义一个proto类型的消息

消息的核心内容如下:

cs 复制代码
message ChargingCmd {
    string cmd = 1;
}

2、使用前面博客介绍的方法将消息转为Java类ChargingCmdProtobuf

3、创建一个消息类型转换处理器

java 复制代码
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @author: 
 * @Desc:消息类型转换处理器
 * @create: 2025-10-03 18:04
 **/
@Slf4j
public class ProtobufMsgToMsgHandler extends MessageToMessageDecoder<WebSocketFrame> {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, WebSocketFrame webSocketFrame, List<Object> list) throws Exception {
        // 判断WebSocketFrame类型,如果是TextWebSocketFrame,则进行处理
        if (webSocketFrame instanceof TextWebSocketFrame) {
            //转为字符串类型
            String text = ((TextWebSocketFrame) webSocketFrame).text();
            log.info("WebSocket收到消息:{}", text);
			
		 //处理二进制消息,protobuf消息正是以二进制形式传输的
        }else if(webSocketFrame instanceof BinaryWebSocketFrame){
            ByteBuf bytes = ((BinaryWebSocketFrame) webSocketFrame).content();
            //添加到list中,交给下一个handler处理
            list.add(bytes);
            //retain引用计数,防止释放
            bytes.retain();
        }
    }
}

核心代码:

复制代码
//处理二进制消息,protobuf消息以二进制形式传输的
if(webSocketFrame instanceof BinaryWebSocketFrame){
    ByteBuf bytes = ((BinaryWebSocketFrame) webSocketFrame).content();
    //添加到list中,交给下一个handler处理
    list.add(bytes);
    //retain引用计数,防止释放
    bytes.retain();
}

4、创建一个反序列化处理器

java 复制代码
@Slf4j
public class ProtobufDeserializeHandler extends SimpleChannelInboundHandler<ChargingCmdProtobuf.ChargingCmd> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ChargingCmdProtobuf.ChargingCmd chargingCmd) throws Exception {
        log.info("接收到小程序发送过来的指令为:{}", chargingCmd.getCmd());
    }
}

5、Websocket入站处理器增加protobuf消息的处理

java 复制代码
    /**
     * 接收到消息时触发,处理WebSocket消息
     * @param channelHandlerContext
     * @param webSocketFrame
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, WebSocketFrame webSocketFrame) throws Exception {
        // 判断WebSocketFrame类型,如果是TextWebSocketFrame,则进行处理
        if (webSocketFrame instanceof TextWebSocketFrame) {
           //转为字符串类型
            String text = ((TextWebSocketFrame) webSocketFrame).text();
            log.info("WebSocket收到消息:{}", text);
       }else if(webSocketFrame instanceof BinaryWebSocketFrame){
            //处理二进制消息,protobuf消息正是以二进制形式传输的
            byte[] bytes = ((BinaryWebSocketFrame) webSocketFrame).content().array();
            log.info("WebSocket收到二进制消息:{}", bytes);
        }
    }

6、自定义通道处理器添加上以上添加的处理器

java 复制代码
/**
 * @Desc:自定义通道初始化器
 * @create: 2025-10-01 10:04
 * 
 **/
public class MyChannelInit extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        //取出channelPipeline
        ChannelPipeline pipeline = socketChannel.pipeline();
        /* *
         * Netty内置了很多编码解码器
         * 1、HttpServerCodec:HTTP解码器,用于处理HTTP请求
         * Netty中以Codec为后缀的类,一般都是编码解码器,既可以编码也可以解码
         * HttpServerCodec只能处理HTTP get请求,不能处理post请求
         * 2、HttpObjectAggregator:可处理Http POST请求,用于将多个Http消息聚合为完整的HTTP请求
         * HttpObjectAggregator能够将HttpMessage和HttpContent聚合为FullHttpRequest或FullHttpResponse
         *
         **/
        pipeline
                //添加Netty内置的读写超时的处理器
                .addLast(new IdleStateHandler(30,30,30, TimeUnit.SECONDS))
                //添加自定义心跳检测处理器
                .addLast(new MyServerHeartBeatHandler())
                //处理HTTP GET请求
                .addLast(new HttpServerCodec())
                //处理HTTP POST请求,聚合Http消息,防止粘包
                .addLast(new HttpObjectAggregator(1048576))
                //处理WebSocket请求
                .addLast(new WebSocketServerProtocolHandler("/ws"))
                //添加消息转换处理器,将WebSocketFrame消息转换为ProtoBuf二进制类型的消息
                .addLast(new ProtobufMsgToMsgHandler())
                //接收数据,对ProtoBu数据进行反序列化,返回的是ChargingCmd对象,ChargingCmdProtobuf.ChargingCmd是我们定义的消息类型,
                .addLast(new ProtobufDecoder(ChargingCmdProtobuf.ChargingCmd.getDefaultInstance()))
                //发送数据,对ProtoBu数据进行序列化
                .addLast(new ProtobufDeserializeHandler())
                //发送数据,ProtoBu序列化
                .addLast(new ProtobufEncoder())
                //自定义处理器
                .addLast(new WebSocketInboundHandler());
    }
}

核心代码:

//添加消息转换处理器,将WebSocketFrame消息转换为ProtoBuf二进制类型的消息

.addLast(new ProtobufMsgToMsgHandler())

//接收数据,对ProtoBu数据进行反序列化,返回的是ChargingCmd对象,ChargingCmdProtobuf.ChargingCmd是我们定义的消息类型,

.addLast(new ProtobufDecoder(ChargingCmdProtobuf.ChargingCmd.getDefaultInstance()))

//发送数据,对ProtoBu数据进行序列化

.addLast(new ProtobufDeserializeHandler())

//发送数据,ProtoBu序列化

.addLast(new ProtobufEncoder())

//自定义处理器

.addLast(new WebSocketInboundHandler());

相关推荐
yinchnag17 小时前
proto协议统计带宽字节流量
protobuf
TickDB1 天前
Python 调用实时行情 API:ticker 返回成功后,如何校验字段再入库或展示
python·websocket·行情数据 api
The_Ticker1 天前
港股量化实测:实时行情接口性能与数据质量深度解析
python·websocket·算法·金融
xujinwei_gingko1 天前
SpringBoot整合WebSocket
spring boot·后端·websocket
天天进步20152 天前
Tunnelto 源码解析 #9:控制服务器设计:Warp、WebSocket、Ping/Pong 与连接保活
运维·服务器·websocket
咖啡星人k3 天前
MonkeyCode 网络架构:WebSocket、SSE与实时协作的技术选型
网络·websocket·架构·monkeycode
tobias.b3 天前
JumpServer4\.10\.16离线部署\+外部Nginx反向代理 解决30分钟空闲断开WebSocket超时(延长10天)
运维·websocket·nginx
Jacob程序员3 天前
WebSSH技术实现全解析
linux·运维·服务器·websocket
brycegao3213 天前
金融交易App客户端架构实战 | 模块化、WebSocket治理、多线路容灾全解
websocket·金融·组件化·android架构·客户端模块化·移动端稳定性·多线路网络
不懂的浪漫3 天前
10|Netty native epoll 与零拷贝:从 Java NIO 再往下看一层![
java·netty·nio