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 out) throws Exception {

        ChannelPipeline pipeline = ctx.channel().pipeline();
        boolean skip = skipControlCharacters(in);
        List 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. 代码链接地址

你可能感兴趣的:(netty,Netty,tcp,websocket)