热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Netty中怎么实现websocket发消息

本篇内容介绍了“Netty中怎么实现websocket发消息”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习

本篇内容介绍了“Netty中怎么实现websocket发消息”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1、pom文件

    io.netty
    netty-all
    4.1.25.Final
2、index.html

   
      
      
   
   
      
发送消息:
                           
接受消息:
      
                 
3、main函数
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class WSServer {

   public static void main(String[] args) throws Exception {
      
      //定义一对线程组 
      // 主线程组, 用于接受客户端的连接,但是不做任何处理,跟老板一样,不做事      
      EventLoopGroup mainGroup = new NioEventLoopGroup();
      // 从线程组, 老板线程组会把任务丢给他,让手下线程组去做任务
      EventLoopGroup subGroup = new NioEventLoopGroup();
      
      try {
         // netty服务器的创建, ServerBootstrap 是一个启动类
         ServerBootstrap server = new ServerBootstrap();
         server.group(mainGroup, subGroup)    // 设置主从线程组
            .channel(NioServerSocketChannel.class)    // 设置nio的双向通道
            .childHandler(new WSServerInitialzer());  //// 子处理器,用于处理workerGroup
         
         // 启动server,并且设置8088为启动的端口号,同时启动方式为同步
         ChannelFuture future = server.bind(8088).sync();
         
         future.channel().closeFuture().sync();
      } finally {
         // 监听关闭的channel,设置位同步方式
         mainGroup.shutdownGracefully();
         subGroup.shutdownGracefully();
      }
   }
}
4、初始化类
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.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class WSServerInitialzer extends ChannelInitializer {

   @Override
   protected void initChannel(SocketChannel ch) throws Exception {
      ChannelPipeline pipeline = ch.pipeline();
      
      // websocket 基于http协议,所以要有http编解码器
      pipeline.addLast(new HttpServerCodec());
      // 对写大数据流的支持 
      pipeline.addLast(new ChunkedWriteHandler());
      // 对httpMessage进行聚合,聚合成FullHttpRequest或FullHttpResponse
      // 几乎在netty中的编程,都会使用到此hanler
      pipeline.addLast(new HttpObjectAggregator(1024*64));
      
      // ====================== 以上是用于支持http协议    ======================
      
      // ====================== 以下是支持httpWebsocket ======================
      
      /**
       * websocket 服务器处理的协议,用于指定给客户端连接访问的路由 : /ws
       * 本handler会帮你处理一些繁重的复杂的事
       * 会帮你处理握手动作: handshaking(close, ping, pong) ping + pong = 心跳
       * 对于websocket来讲,都是以frames进行传输的,不同的数据类型对应的frames也不同
       */
      pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
      
      // 自定义的handler
      pipeline.addLast(new ChatHandler());
   }
}
5、助手类
import io.netty.channel.Channel;
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.GlobalEventExecutor;

/**
 * 
 * @Description: 处理消息的handler
 * TextWebSocketFrame: 在netty中,是用于为websocket专门处理文本的对象,frame是消息的载体
 */
public class ChatHandler extends SimpleChannelInboundHandler {

   // 用于记录和管理所有客户端的channle
   private static ChannelGroup clients = 
         new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
   
   @Override
   protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) 
         throws Exception {
      // 获取客户端传输过来的消息
      String content = msg.text();
      System.out.println("接受到的数据:" + content);

      //类似于for循环
      clients.writeAndFlush(
            new TextWebSocketFrame(
                  "[服务器在]" + LocalDateTime.now() 
                  + "接受到消息, 消息为:" + content));
   }

   /**
    * 当客户端连接服务端之后(打开连接)
    * 获取客户端的channle,并且放到ChannelGroup中去进行管理
    */
   @Override
   public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
      clients.add(ctx.channel());
   }

   @Override
   public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
      // 当触发handlerRemoved,ChannelGroup会自动移除对应客户端的channel
//    clients.remove(ctx.channel());
      System.out.println("客户端断开,channle对应的长id为:" 
                     + ctx.channel().id().asLongText());
      System.out.println("客户端断开,channle对应的短id为:" 
                     + ctx.channel().id().asShortText());
   }
}
6、测试

运行index.html

发送消息,如下server端返回消息

Netty中怎么实现websocket发消息

“Netty中怎么实现websocket发消息”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程笔记网站,小编将为大家输出更多高质量的实用文章!


推荐阅读
  • FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路
    本文介绍了FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路。当图表系列较多时,用户希望可以自己设置哪些系列显示,哪些系列不显示。通过调用FR.Chart.WebUtils.getChart("chartID").getChartWithIndex(chartIndex).setSeriesVisible()接口,可以获取需要显示的系列图表对象,并在表单中显示这些系列。本文以决策报表为例,详细介绍了实现方法,并给出了示例。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
author-avatar
年轮033
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有