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

相关推荐
Yeswater3 小时前
从 NIO 到 Netty:五个坑,和一张把它填平的基础设施网
java·后端·netty
张张123y17 小时前
后端第一课:输入 URL 后发生了什么?我用手写 Socket 把全链路跑通了
python·websocket·ai·socket·url·后端开发
paopaokaka_luck1 天前
民宿管理系统 (AI民宿总结、协同过滤推荐算法、WebSocket 在线咨询、ECharts 经营分析、房态与结算联动、 民宿预订业务闭环)
java·人工智能·spring boot·websocket·数据分析·echarts·推荐算法
云梦谭2 天前
WebSocket 协议详解:从 HTTP 握手到全双工通信
websocket·网络协议·http
光依旧2 天前
MCP实战手记(十一):MCP接飞书,从机器人到事件订阅的三层深度接入
websocket·事件驱动架构·大模型应用开发·spring ai·企业系统集成·mcp·飞书开放平台
ab1237683 天前
Spring WebSocket(STOMP)
笔记·websocket·springboot·stomp
hellojackjiang20113 天前
IM聊天不掉线?生产级WebSocket断线重连、心跳保活实战
websocket·网络协议·网络编程·html5·即时通讯·im
paopaokaka_luck3 天前
剧本杀预约管理系统(AI客服、 webSocket在线沟通、协同过滤算法推荐、Echarts多维分析、 QQ邮箱通知、 腾讯地图导航、四角色协作)
websocket·网络协议·echarts
事圆则缓4 天前
Android 中的 Socket 和 WebSocket:从一条聊天消息看清区别
android·websocket·网络协议