Netty 同一个端口支持Tcp和 websocket

  1. 在Netty 实战群里讨论了下能否一个端口支持tcp和websocket . 既然websocket是从http升级到websocket的 Netty能判断http的话 理论上能判断出是http的话,那就应该可以的。服务器监听端口,在最开始添加一个decode 这里判断是tcp还是http 来选择添加对应的编解码器。既然理论上行的通 ,那现在就开始验证下吧。
  2. 服务器端添加一个SelectDecode
package com.next.network;

import com.next.network.tcp.DataObjectDecode;
import com.next.network.tcp.DataObjectEncode;
import com.next.network.tcp.NettyServerHandler;
import com.next.network.websocket.LineParser;
import com.next.network.websocket.WebSocketFrameHandler;
import com.next.network.websocket.WebSocketIndexPageHandler;
import com.next.server.Server;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
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.util.CharsetUtil;
import io.netty.util.internal.AppendableCharSequence;

import java.util.List;

public class SelectDecode extends ByteToMessageDecoder {

    private final LineParser lineParser;


    public SelectDecode() {
        AppendableCharSequence seq = new AppendableCharSequence(128);
        lineParser = new LineParser(seq, 4096);

    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

        ChannelPipeline pipeline = ctx.channel().pipeline();
        boolean skip = skipControlCharacters(in);
        List<ChannelHandler> list = null;
        //tcp
        if (!skip) {
            list = Server.getInstance().getTcpHandler();

        } else {
            //http
            list = Server.getInstance().getWebsocketHandler();
        }
        for (ChannelHandler ch : list) {
            pipeline.addLast(ch);
        }
        pipeline.remove(this);
    }

    private boolean skipControlCharacters(ByteBuf buffer) {
        buffer.markReaderIndex();
        buffer.markWriterIndex();
        boolean skiped = false;
        final int wIdx = buffer.writerIndex();
        int rIdx = buffer.readerIndex();
        while (wIdx > rIdx) {
            int c = buffer.getUnsignedByte(rIdx++);
            if (!Character.isISOControl(c) && !Character.isWhitespace(c)) {
                rIdx--;
                skiped = true;
                break;
            }
        }
        if (skiped) {
            AppendableCharSequence line = lineParser.parse(buffer);
            if (line == null) {
                skiped = false;
            }
        }
        buffer.readerIndex(rIdx);

        buffer.resetReaderIndex();
        buffer.resetWriterIndex();
        return skiped;
    }

}

这里面有一个关键方法 skipControlCharacters是从Netty的HttpObjectDecoder里面copy过来稍微改了下

  1. 从判断出来是http还是tcp来添加对应的编解码,测试了下,是可以运行的(如果http判断有误的话 可以参考Netty的HttpObjectDecoder的代码多判断些数据)。
  2. 代码链接地址
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Netty是一个异步事件驱动的网络框架,可以通过使用不同的传输协议(如TCP、UDP等)来实现网络通信。Socket是一种基于TCP/IP协议的通信方式,它提供了一种可靠的面向连接的数据传输方式。而WebSocket是一种在单个TCP连接上全双工通信的协议。 在Netty中,可以通过组合的方式来支持使用不同的传输协议和通信方式,包括Socket和WebSocket。当需要在同一个端口上同时支持Socket和WebSocket时,可以通过将相关的ChannelHandler添加到Netty的ChannelPipeline中来实现。 首先,需要创建一个Netty的ServerBootstrap对象,并设置相关的配置参数,如监听端口号等。接下来,可以使用Netty提供的各种ChannelHandler来处理Socket和WebSocket请求。 对于Socket请求,可以使用Netty的SocketChannel和对应的ChannelHandler来处理。通过创建一个自定义的ChannelInitializer,并重写其中的initChannel方法,将SocketChannel和对应的SocketChannelHandler添加到ChannelPipeline中。 对于WebSocket请求,可以使用Netty提供的WebSocketServerProtocolHandler来处理。该Handler可以解析WebSocket握手请求,并将请求升级为WebSocket连接。可以将WebSocketServerProtocolHandler添加到ChannelPipeline的最前面。 通过上述步骤配置好Netty的ServerBootstrap对象后,可以开始监听和接收来自客户端的Socket和WebSocket请求。当有新的连接建立时,Netty会自动调用对应的ChannelHandler来处理请求,包括解析和处理数据。 总的来说,Netty提供了强大的可扩展性和灵活性,可以通过组合不同的ChannelHandler来实现在同一个端口上同时支持Socket和WebSocket通信。这使得开发者可以根据实际需求选择不同的通信方式,并简化了服务器的管理和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值