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());

相关推荐
刘马想放假2 天前
CANviz 使用指南|Linux 安装、DBC 解码、实时曲线与 J1939 实战
linux·python·websocket
张小姐的猫2 天前
【基于 WebSocket 的多用户网页五子棋】—— 项目结构设计与实用工具类模块
网络·websocket·网络协议
新*3 天前
从一段 WebSocket 代码聊开:bytes 不是 zlib、binaryType 决定一切,15MB 大消息的零拷贝优化
javascript·python·websocket·性能优化·blob·zlib·arraybuffer
️公子4 天前
可插拔 13 款实时棋牌对战平台实践:房间容器、Plugin SDK 与幂等账本
websocket·typescript·游戏开发·monorepo·插件架构·棋牌平台·实时对战
你三大爷7 天前
三个Handler一个任务-Netty事件传播的任务边界设计
netty
我不会起名字32210 天前
Redis 从 0 到 1(二十七):JSON 体积是 Protobuf 的 3.7 倍?3 种序列化的 Go 基准测试
redis·go·序列化·protobuf·messagepack
guizhoumen11 天前
net core下WebSocket请求总是断开的解决方案
网络·websocket·网络协议
QianhangQianping12 天前
WebSocket实时推送+ HTTP 定时轮询:一块大屏两套取数怎么不打架
前端·websocket·网络协议·http·低代码·架构·数据可视化
web打印社区13 天前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket
Da Da 泓14 天前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目