[ Netty ](四) 基于 webSocket 实现客户端与客户端通信(网页聊天实例)

实现的功能

  • 多客户端通信(群聊)
    在这里插入图片描述

具体实现代码

客户端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网页聊天室</title>
</head>

<body>
        输入消息:<input type="text" id="msgContent">
        <input type="button" value="发送" onclick="CHAT.chat()">
        <div id="receiveMsg" style="background-color: gainsboro;"></div>
    <script>
        window.CHAT = {
            socket: null,
            init: function () {
                if (window.WebSocket) {
                    CHAT.socket = new WebSocket("ws://192.168.43.178:8899/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 + "<br/>" + e.data;
                        }
                } else {
                    alert("浏览器不支持WebSocket")
                }
            },
            chat: function () {
                var msg = document.getElementById("msgContent")
                CHAT.socket.send(msg.value)
            }
        }
        CHAT.init()
    </script>
</body>

</html>

服务端

  • WebSocketServer
public class WebSocketServer {
    public static void main(String[] args) throws  Exception{
        //两个线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            //启动服务器
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).
                    childHandler(new WebSocketChannelInitializer());

            ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899)).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();// 关闭线程组
            workerGroup.shutdownGracefully();
        }
    }
}

  • WebSocketChannelInitializer
public class WebSocketChannelInitializer  extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new ChunkedWriteHandler());
        pipeline.addLast(new HttpObjectAggregator(8192));
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        pipeline.addLast(new TextWebSocketFrameHandler());

    }
}
  • TextWebSocketFrameHandler
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private static ChannelGroup clients =
            new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        String content = msg.text();
        for(Channel channel: clients) {
            channel.writeAndFlush(
                    new TextWebSocketFrame(
                            "[服务器在]"+ LocalDateTime.now()+"接收到消息,消息为:"+content));
        }
//        clients.writeAndFlush(
//                new TextWebSocketFrame(
//                        "[服务器在]"+ LocalDateTime.now()+"接收到消息,消息为:"+content));
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        clients.add(ctx.channel());
        System.out.println("handlerAdd:" + ctx.channel().id().asLongText());
    }

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

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("异常发生");
        ctx.close();
    }
}


在这里插入图片描述

发布了126 篇原创文章 · 获赞 1072 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/qq_43901693/article/details/104282876