原创

基于netty实现处理websocket的握手协议和消息通信

1.直接上代码

1.最好有netty框架使用基础
2.有socket编程基础
3.了解网络通信相关协议

2.依赖

<dependencies>
        <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.37.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.inject/guice -->
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>4.2.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
    </dependencies>

3.核心处理逻辑

服务端接收消息简单处理

    @Override
    protected void channelRead0(ChannelHandlerContext context, Object msg) throws Exception {
        System.out.println("有新消息");
        //处理客户端向服务端发起http握手请求业务
        if (msg instanceof FullHttpRequest) {
            handHttpRequest(context, (FullHttpRequest) msg);
        } else if (msg instanceof WebSocketFrame) {//处理websocket连接业务
            handWebsocketFrame(context, (WebSocketFrame) msg);
        }
    }

*服务端处理websocket握手协议

    private void handHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
        if (!req.getDecoderResult().isSuccess() || !("websocket".equals(req.headers().get("Upgrade")))) {
            //处理不是握手请求
            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
            return;
        }

        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(WEB_SOCKET_URL, null, false);
        handshaker = wsFactory.newHandshaker(req);
        if (handshaker == null) {
            WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
        } else {
            handshaker.handshake(ctx.channel(), req);
        }

    }

接收并处理websocket消息

/**
     * 处理客户端与服务端websocket业务
     *
     * @param ctx
     * @param frame
     */
    public void handWebsocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        String fromChannelid = ctx.channel().id().toString();

        //判断是否是关闭websocket的指令
        if (frame instanceof CloseWebSocketFrame) {
            handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
        }

        //判断是否是ping消息
        if (frame instanceof PingWebSocketFrame) {
            System.out.println("ping消息");
            ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
        }

        //判断是否是二进制消息,如果是直接抛出,先不支持二进制消息
        if (!(frame instanceof TextWebSocketFrame)) {
            System.out.println("目前不支持二进制消息");
            throw new RuntimeException("目前不支持二进制消息");
        }

        //返回应答消息
        //获取客户端向服务端发送的消息
        String request = (((TextWebSocketFrame) frame).text()).replaceAll("[\\s*\\t\\n\\r]", "");
        System.out.println("客户端消息"+request);
    }

...前端代码就不发了

4.实现

服务端接收到消息

客户端发送消息

5.

1.大型IM结构

git地址
https://github.com/fireflyi/gerant

2.本文源码

git
https://github.com/fireflyi/xiaoqingxin/tree/master/ws

正文到此结束
本文目录