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

相关推荐
阿里云云原生7 小时前
LoongSuite:解决 WebSocket 全链路可观测性难题,赋能 AI 应用的实时链路追踪
人工智能·websocket·网络协议·阿里云·云原生·可观测
liu****9 小时前
二.protobuf的使用
c++·c·protobuf·企业级组件
..空空的人10 小时前
C++基于protobuf实现仿RabbitMQ消息队列---技术认识2
服务器·数据库·c++·网络协议·gtest·异步·protobuf
unique_perfect21 小时前
vue2与springboot实现deepseek打印机聊天
spring boot·websocket·ai·vue2·deepseek
捧 花1 天前
Go Web 中 WebSocket 原理与实战详解
网络·后端·websocket·网络协议·http·golang·web
想用offer打牌1 天前
一站式了解长轮询,SSE和WebSocket
java·网络·后端·websocket·网络协议·系统架构
代码or搬砖1 天前
flask与vue实现通过websocket通信
vue.js·websocket·flask
2501_921649491 天前
外汇与贵金属行情 API 集成指南:WebSocket 与 REST 调用实践
网络·后端·python·websocket·网络协议·金融
weixin79893765432...1 天前
主流 AI 应用的“流式技术”的探索交流
websocket·sse·ai的流式技术·llm token·http chunked·async generator·message stream
Yu_Lijing2 天前
【个人项目】C++基于websocket的多用户网页五子棋(下)
网络·websocket·网络协议