• netty整合websocket(完美教程)


    websocket的介绍:

    WebSocket是一种在网络通信中的协议,它是独立于HTTP协议的。该协议基于TCP/IP协议,可以提供双向通讯并保有状态。这意味着客户端和服务器可以进行实时响应,并且这种响应是双向的。WebSocket协议端口通常是80,443。

    WebSocket的出现使得浏览器具备了实时双向通信的能力。与HTTP这种非持久单向响应应答的协议相比,WebSocket是一个持久化的协议。举例来说,即使在关闭网页或者浏览器后,WebSocket的连接仍然保持,用户也可以继续接收到服务器的消息。

    此外,要建立WebSocket连接,需要浏览器和服务器握手进行建立连接。一旦连接建立,WebSocket可以在浏览器和服务器之间双向发送或接受信息。总的来说,WebSocket提供了一个高效、实时的双向通信方案。

    1、用netty构建websocket服务器

    1. package org.tianfan.websocket;// WebSocketServer.java
    2. import io.netty.bootstrap.ServerBootstrap;
    3. import io.netty.channel.ChannelFuture;
    4. import io.netty.channel.ChannelInitializer;
    5. import io.netty.channel.ChannelPipeline;
    6. import io.netty.channel.EventLoopGroup;
    7. import io.netty.channel.nio.NioEventLoopGroup;
    8. import io.netty.channel.socket.SocketChannel;
    9. import io.netty.channel.socket.nio.NioServerSocketChannel;
    10. import io.netty.handler.codec.http.HttpObjectAggregator;
    11. import io.netty.handler.codec.http.HttpServerCodec;
    12. import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
    13. public class WebSocketServer {
    14. private final int port;
    15. public WebSocketServer(int port) {
    16. this.port = port;
    17. }
    18. public void run() throws Exception {
    19. EventLoopGroup bossGroup = new NioEventLoopGroup();
    20. EventLoopGroup workerGroup = new NioEventLoopGroup();
    21. try {
    22. ServerBootstrap b = new ServerBootstrap();
    23. b.group(bossGroup, workerGroup)
    24. .channel(NioServerSocketChannel.class)
    25. .childHandler(new ChannelInitializer() {
    26. @Override
    27. public void initChannel(SocketChannel ch) throws Exception {
    28. ChannelPipeline p = ch.pipeline();
    29. p.addLast(new HttpServerCodec());
    30. p.addLast(new HttpObjectAggregator(65536));
    31. p.addLast(new WebSocketServerProtocolHandler("/websocket"));
    32. p.addLast(new WebSocketServerHandler());
    33. }
    34. });
    35. ChannelFuture f = b.bind(port).sync();
    36. f.channel().closeFuture().sync();
    37. } finally {
    38. workerGroup.shutdownGracefully();
    39. bossGroup.shutdownGracefully();
    40. }
    41. }
    42. public static void main(String[] args) throws Exception {
    43. int port = 8080;
    44. if (args.length > 0) {
    45. port = Integer.parseInt(args[0]);
    46. }
    47. new WebSocketServer(port).run();
    48. }
    49. }

    我来解释一下上面的代码:

    • p.addLast(new HttpServerCodec()):添加HTTP服务器编解码器,用于将数据转换成HTTP协议格式进行传输。
    • p.addLast(new HttpObjectAggregator(65536)):添加HTTP对象聚合处理器,用于将HTTP请求或响应中的多个消息片段聚合成完整的消息。
    • p.addLast(new WebSocketServerProtocolHandler("/websocket")):添加WebSocket协议处理器,用于处理WebSocket握手、消息传输等操作。
    • p.addLast(new WebSocketServerHandler()):添加WebSocket处理器,用于处理客户端与服务器端之间的数据交换,实现自定义的业务逻辑。

    使用Netty框架中的WebSocketServerProtocolHandler处理器,将HTTP升级为WebSocket协议。它创建了一个新的管道(pipeline)并将WebSocket处理程序添加到管道的尾部,以便处理WebSocket协议的握手和帧。"/websocket"是WebSocket的URI路径,它指定了WebSocket服务的相对地址,该地址将在客户端请求连接时被指定。

    1. package org.tianfan.websocket;
    2. import io.netty.channel.ChannelHandlerContext;
    3. import io.netty.channel.SimpleChannelInboundHandler;
    4. import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
    5. public class WebSocketServerHandler extends SimpleChannelInboundHandler {
    6. @Override
    7. public void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
    8. // 处理消息
    9. System.out.println("Received message: " + msg.text());
    10. ctx.channel().writeAndFlush(new TextWebSocketFrame("Server received: " + msg.text()));
    11. }
    12. @Override
    13. public void channelActive(ChannelHandlerContext ctx) throws Exception {
    14. // 添加连接
    15. System.out.println("Client connected: " + ctx.channel());
    16. }
    17. @Override
    18. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    19. // 断开连接
    20. System.out.println("Client disconnected: " + ctx.channel());
    21. }
    22. @Override
    23. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    24. // 异常处理
    25. cause.printStackTrace();
    26. ctx.close();
    27. }
    28. }

    我来解释一下上面的代码:

    刚信息发过来的时候,在服务端打印,并写入前端。

    2、前端客户端页面:

    1. <!-- index.html -->
    2. <!DOCTYPE html>
    3. <html>
    4. <head>
    5. <meta charset="UTF-8">
    6. <title>WebSocket Test</title>
    7. </head>
    8. <body>
    9. <h1>WebSocket Test</h1>
    10. <div>
    11. <input type="text" id="message" placeholder="Message">
    12. <button onclick="send()">Send</button>
    13. </div>
    14. <div id="output"></div>
    15. <script>
    16. var socket = new WebSocket("ws://localhost:8080/websocket");
    17. socket.onopen = function(event) {
    18. console.log("WebSocket opened: " + event);
    19. };
    20. socket.onmessage = function(event) {
    21. console.log("WebSocket message received: " + event.data);
    22. var output = document.getElementById("output");
    23. output.innerHTML += "

      " + event.data + "

      "
      ;
    24. };
    25. socket.onclose = function(event) {
    26. console.log("WebSocket closed: " + event);
    27. };
    28. function send() {
    29. var message = document.getElementById("message").value;
    30. socket.send(message);
    31. }
    32. </script>
    33. </body>
    34. </html>

    运行结果:

  • 相关阅读:
    Seal-Report: 开放式数据库报表工具
    基于C语言的词法分析程序的设计与实现
    Element-UI el-select下拉框多选实现全选
    【树莓派不吃灰】搭建Node-Red可拖拽图形化物联网
    『时代』杂志:元宇宙将改变世界;健身教练:AI让我丢工作!有话说北欧人工智能夏令营资料大公开;深度学习书籍TOP5 | ShowMeAI资讯日报
    windbg的时间旅行实现对 C# 程序的终极调试
    Can only call getServletHandlers on a running MetricsSystem解决方法
    UI Toolkit 计时器
    2022电工(初级)上岗证题目及答案
    链表-链表的中间节点
  • 原文地址:https://blog.csdn.net/m0_63251896/article/details/134518001