SpringBoot+Netty实现CS交互(一)

添加依赖

 <dependency>
     <groupId>io.nettygroupId>
     <artifactId>netty-allartifactId>
     <version>4.1.25.Finalversion>
 dependency>

ws服务端

package com.imooc.netty.websocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author 朝花不迟暮
 * @version 1.0
 * @date 2020/12/28 22:21
 */
public class WSServer
{
     
    public static void main(String[] args)
    {
     
        //主子线程组
        NioEventLoopGroup mainGroup = new NioEventLoopGroup();
        NioEventLoopGroup subGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = null;
        try
        {
     
            serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(mainGroup, subGroup)//设置主从线程组
                    .channel(NioServerSocketChannel.class)//设置nio双向通道
                    .childHandler(new WSServerInitializer());//子处理器,用于处理workerGroup
            ChannelFuture future = serverBootstrap.bind(8088).sync();
            //监听关闭的channel,设置为同步方式
            future.channel().closeFuture().sync();
        } catch (Exception e)
        {
     
            e.printStackTrace();
        } finally
        {
     
            //优雅关闭
            mainGroup.shutdownGracefully();
            subGroup.shutdownGracefully();
        }
    }
}

子处理器

package com.imooc.netty.websocket;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @author 朝花不迟暮
 * @version 1.0
 * @date 2020/12/28 22:37
 */
public class WSServerInitializer extends ChannelInitializer<SocketChannel>
{
     

    @Override
    protected void initChannel(SocketChannel ch) throws Exception
    {
     
        ChannelPipeline pipeline = ch.pipeline();
        //ws基于http协议,所以要有编解码器
        pipeline.addLast(new HttpServerCodec());
        //对写入大数据流的支持
        pipeline.addLast(new ChunkedWriteHandler());
        //在netty中,几乎都会使用到这个handler
        pipeline.addLast(new HttpObjectAggregator(1024 * 64));
        //服务器处理的协议,用户给客户端连接访问的路由
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        // 自定义的handler
        pipeline.addLast(new ChatHandler());
    }
}

该类继承ChannelInitializer,泛型为SocketChannel!通过获取的管道,使用addLast添加ws的基本配置。上面的代码就是基本配置!

自定义消息处理

package com.imooc.netty.websocket;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.time.LocalDateTime;

/**
 * @author 朝花不迟暮
 * @version 1.0
 * @date 2020/12/28 22:52
 */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>
{
     
    //用户记录和管理所有客户端的channel
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception
    {
     
        //获取客户端传输的消息
        String msgText = msg.text();
        System.out.println("接收到的数据: " + msgText);
//        for (Channel client : clients)
//        {
     
//            client.writeAndFlush(new TextWebSocketFrame("[服务器接收到的消息]"
//                    + LocalDateTime.now() + " 接收到的消息为: " + msgText));
//        }
        clients.writeAndFlush(new TextWebSocketFrame("[服务器接收到的消息]"
                + LocalDateTime.now() + " 接收到的消息为: " + msgText));
    }

    /**
     * @Description: 当客户端连接服务端之后, 获取到客户端的channel, 并且放到channelGroup中
     * @Param: ctx
     * @return:
     * @Author: 朝花不迟暮
     * @Date: 2020/12/28
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception
    {
     
        Channel channel = ctx.channel();
        clients.add(channel);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception
    {
     
        System.out.println("长id: " + ctx.channel().id().asLongText());
        System.out.println("短id: " + ctx.channel().id().asShortText());
    }
}

前端页面


<html>
<head>
    <meta charset="utf-8"/>
    <title>title>
head>
<body>

<div>发送消息:div>
<input type="text" id="msgContent"/>
<input type="button" value="点我发送" onclick="CHAT.chat()"/>

<div>接受消息:div>
<div id="receiveMsg" style="background-color: gainsboro;">div>

<script type="application/javascript">

    window.CHAT = {
      
        socket: null,
        init: function () {
      
            if (window.WebSocket) {
      
                CHAT.socket = new WebSocket("ws://192.168.0.102:8088/ws");
                CHAT.socket.onopen = function () {
      
                    console.log("连接建立成功...");
                },
                    CHAT.socket.onclose = function () {
      
                        console.log("连接关闭...");
                    },
                    CHAT.socket.onerror = function () {
      
                        console.log("发生错误...");
                    },
                    CHAT.socket.onmessage = function (e) {
      
                        console.log("接受到消息:" + e.data);
                        var receiveMsg = document.getElementById("receiveMsg");
                        var html = receiveMsg.innerHTML;
                        receiveMsg.innerHTML = html + "
"
+ e.data; } } else { alert("浏览器不支持websocket协议..."); } }, chat: function () { var msg = document.getElementById("msgContent"); CHAT.socket.send(msg.value); } }; CHAT.init();
script> body> html>

测试效果

SpringBoot+Netty实现CS交互(一)_第1张图片
SpringBoot+Netty实现CS交互(一)_第2张图片

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