请教一个问题,netty 怎么实现同时处理 java 客户端的 tcp 连接 和 js 端的Websocket 连接

发布于 2022-09-11 19:38:42 字数 3476 浏览 13 评论 0

问题描述

实现的功能就是 js 端 websocket 连接用于接收消息,发送消息通过 http 请求到 java 提供的服务,然后这个 java 服务推送 消息到 websocket 上面,所以就需要 netty 启用的 服务既 支持 java 写的客户端tcp连接 又 支持 js 前端的 websocket 的连接

完整代码: 完整问题代码

下面是部分代码,这段示例代码没有效果:

package com.example.nettydemo.websocket3;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.CharsetUtil;

/**
 * 协议解码处理器,用来判断使用的什么协议(本例是指WebSocket还是TcpSocket),从而动态修改编解码器
 *
 * @author lucher
 *
 */
public class ProtocolDecoder extends ByteToMessageDecoder {

    /**
     * 请求行信息的长度,ws为:GET /ws HTTP/1.1, Http为:GET / HTTP/1.1
     */
    private static final int PROTOCOL_LENGTH = 16;
    /**
     * WebSocket握手协议的前缀, 本例限定为:GET /ws ,在访问ws的时候,请求地址需要为如下格式 ws://ip:port/ws
     */
    private static final String WEBSOCKET_PREFIX = "GET /ws";

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        String protocol = getBufStart(in);
        ChannelPipeline pipeline = ctx.channel().pipeline();
        System.out.println("ProtocolHandler protocol:" + protocol);
        if (protocol.startsWith(WEBSOCKET_PREFIX)) {
            // websocket协议本身是基于http协议的,所以这边也要使用http解编码器
            pipeline.addLast(new HttpServerCodec());
            // netty是基于分段请求的,HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
            pipeline.addLast(new HttpObjectAggregator(65536));
            // 用于向客户端发送Html5文件,主要用于支持浏览器和服务端进行WebSocket通信
            pipeline.addLast(new ChunkedWriteHandler());
            pipeline.addLast(new WebSocketServerCompressionHandler());
            pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true));
        } else {
            // TcpSocket协议处理
            pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
            pipeline.addLast(new LengthFieldPrepender(4));
            //字符串解码
            pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
            //字符串编码
            pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
        }
        // 重置index标记位
        in.resetReaderIndex();
        // 移除该协议处理器,该channel后续的处理由对应协议安排好的编解码器处理
        pipeline.remove(this);
    }

    /**
     * 获取buffer中指定长度的信息
     *
     * @param in
     * @return
     */
    private String getBufStart(ByteBuf in) {
        int length = in.readableBytes();
        if (length > PROTOCOL_LENGTH) {
            length = PROTOCOL_LENGTH;
        }
        // 标记读取位置
        in.markReaderIndex();
        byte[] content = new byte[length];
        in.readBytes(content);
        return new String(content);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

策马西风 2022-09-18 19:38:42

请问大佬们解决了吗,遇到同样问题了,有什么方案吗@临风 @lmxdawn @Fiee

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文