默认
发表评论 4
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
求教websocket自定义编解码器出现的问题
阅读(21507) | 评论(4 收藏 淘帖
想做一个网页聊天+小游戏的网站,然后就用到了websocket嘛。

在一本书上看到说,用json数据编解码会携带很多没有用的数据,像字段名、大括号、引号这些,会影响效率和占用带宽。然后就想自定义一个编码器来序列化。
@Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            //对workerGroup的SocketChannel设置处理器
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast("logging", new LoggingHandler(LogLevel.INFO));
                            //pipeline.addLast(new DelimiterBasedFrameDecoder(1024, Unpooled.copiedBuffer("_".getBytes())));
                            pipeline.addLast(new HttpServerCodec());
                            pipeline.addLast(new HttpObjectAggregator(1024 * 10));
//                            pipeline.addLast(new WebSocketServerProtocolHandler("/"));
//自定义编解码器
                            pipeline.addLast("EncodeHandler",new EncodeHandler());
                            pipeline.addLast("DecodeHandler", new DecodeHandler());

                            //处理客户端发送的消息
                             pipeline.addLast(chatChannelHandler);
                            //检测心跳,如果用户一段时间没有发送消息则断开连接
                            pipeline.addLast(new ReadTimeoutHandler(30, TimeUnit.MINUTES));
                        }

自定义编码器EncodeHandler:
public class EncodeHandler extends MessageToByteEncoder<GameMessagePackage> {
    private static final int GAME_MESSAGE_HEADER_LEN = 29;
    @Setter
    private String aesSecret;// 对称加密密钥
    @Override
    protected void encode(ChannelHandlerContext ctx, GameMessagePackage msg, ByteBuf out) throws Exception {
        System.out.println("进入自定义编码器");
        int messageSize = GAME_MESSAGE_HEADER_LEN;
        final byte[] body = msg.getBody();
         byte compress = 0;
        if (body != null) {
            // 达到压缩条件,进行压缩
//            if (body.length >= serverConfig.getCompressMessageSize()) {
//                body = CompressUtil.compress(body);
//                compress = 1;
//            }
//            if (this.aesSecret != null && msg.getHeader().getMessageId() != 1) {
//                body = AESUtils.encode(aesSecret, body);
//            }
            messageSize += body.length;
        }
        final GameMessageHeader header = msg.getHeader();
        out.writeInt(messageSize);
        out.writeInt(header.getClientSeqId());
        out.writeInt(header.getMessageId());
        out.writeInt(header.getServiceId());
        out.writeLong(header.getServerSendTime());
        out.writeInt(header.getVersion());
        out.writeByte(compress);
        out.writeInt(header.getErrorCode());
        if (body != null) {
            out.writeBytes(body);
        }
    }
}


前端:
export function createWebSocket(param,$this){
    // getData("/chat/allocation",{ userId: param.id }, "post").then((res) => {
    //     let socket = new WebSocket(res);
    //     return socket;
    // })
    console.log('建立websocket连接:')
    let socket = new WebSocket("ws://localhost:9003/websocket/312");
    socket.onopen = function (event) {
        $this.$notify({
            title: '成功',
            message: '服务器连接成功',
            type: 'success'
        });
    };
    socket.onclose = function (event) {
        $this.$notify({
            title: '警告',
            message: '服务器已断开连接',
            type: 'warning'
        });
    };
    socket.onmessage = function (event) {
        console.log(event);
        // $this.$notify({
        //     title: '收到消息',
        //     message: JSON.parse(event.data),
        //     type: 'info'
        // });
    }
    return socket;
}

我知道这样前端肯定是会有问题的,因为前端默认是解析按json格式进行解码的嘛,然后就在网上找前端websocket自定义解码器
但是找了一下午都没有找到相关的帖子
难道是我的方向错了嘛?救命
前端报错:
WebSocket connection to 'ws://localhost:9003/websocket/312' failed: Received unexpected continuation frame.
我究竟错哪里了,求大神指导我,我一定改!

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

推荐方案
评论 4
别炫技了,退一步,先把JSON数据格式跑通了再玩别的
引用:JackJiang 发表于 2022-03-09 21:21
别炫技了,退一步,先把JSON数据格式跑通了再玩别的

JSON没问题呀,消息用TextWebSocketFrame 走HttpServerCodec就通了。这不是想玩一下嘛感觉挺有意思的
引用:GuangYuanLee 发表于 2022-03-09 21:34
JSON没问题呀,消息用TextWebSocketFrame 走HttpServerCodec就通了。这不是想玩一下嘛感觉挺有意思的

你这就是没事折腾。我没这么玩过,所以没办法给到你具体的意见了
引用:JackJiang 发表于 2022-03-11 11:37
你这就是没事折腾。我没这么玩过,所以没办法给到你具体的意见了

确实是折腾,哈哈哈听大哥的
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部