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

相关推荐
++==5 小时前
ProtoBuf:序列化与反序列化、基础数据结构、关键词、数据格式
序列化·protobuf
Sylvia33.14 小时前
LOL实时数据接入深度解析:从WebSocket到完整数据模型
java·网络·python·websocket·网络协议
鲨鱼辣钊2 天前
FastAPI进阶_Day21_WebSocket实时通讯实战
websocket·网络协议·fastapi
秋田君2 天前
Qt_webSocket协议编程实战
开发语言·qt·websocket
haerapi2 天前
流式对话接口怎么选:SSE 与 WebSocket 的原理、实现和工程边界
网络·websocket·网络协议
予昊3 天前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
隔窗听雨眠3 天前
大模型实时通信协议深度对比:SSE、WebSocket与gRPC的选型指南与实战解析
网络·websocket·网络协议
艾莉丝努力练剑5 天前
【AI大模型接入SDK】WebSocket & SSE 协议
网络·c++·websocket·网络协议·学习·面试
虎王物联6 天前
PHP Swoole实现物联网MQTT数据订阅与WebSocket实时推送
物联网·mqtt·websocket·php·swoole