【使用Netty实现群发消息】

news2024/11/16 22:25:32

使用Netty实现群发消息

  • netty简单介绍
  • 实现群发流程图
  • 代码实现
    • NettyServer 类
    • MyChannelInitializer 类
    • MyServerHandler 类
    • ChannelHandler 类
    • Netty 依赖
  • 效果展示
    • netAssist 工具
    • 启动Netty server
    • 打开netAssist 工具

netty简单介绍

Netty是由JBOSS提供的一个java开源框架,Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
今天我们简单的使用Netty 来实现下群发功能.

实现群发流程图

流程图比较详细。看图应该就差不多了。不清楚的,后面有详细代码粘贴。
在这里插入图片描述

代码实现

NettyServer 类

public static void main(String[] args) {
        try {
            new NettyServer().bind(8080);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void bind(int port) throws InterruptedException {
        //配置服务端线程组
        EventLoopGroup parentGroup=new NioEventLoopGroup();
        EventLoopGroup childGroup=new NioEventLoopGroup();
        ServerBootstrap bootstrap=new ServerBootstrap();
        bootstrap.group(parentGroup,childGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG,128)
                //配置初始化Channel类
                .childHandler(new MyChannelInitializer());
        ChannelFuture future=bootstrap.bind(port).sync();
        System.out.println("echo test.........66666");
        future.channel().closeFuture().sync();
    }

MyChannelInitializer 类

public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
    protected void initChannel(SocketChannel  channel) throws Exception {
        //解码器
        //基于换行符号
        channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
        //基于指定字符串(换行符),这样功能和LineBaseFrameDecoder的功能类似
        //解码转String,注意调整自己的编码格式
        channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));

        //编码格式
        channel.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
        //在管道中添加我们自己的接收数据实现方法
        channel.pipeline().addLast(new MyServerHandler());
    }


}

MyServerHandler 类

public class MyServerHandler extends ChannelInboundHandlerAdapter {
    private SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");

    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object obj) throws UnsupportedEncodingException {
        System.out.println(sdf.format(new Date()) + "\n" + obj);
        //接收数据
        String str = "服务端接收到了消息:" + sdf.format(new Date());
        //通知客户端
        //ByteBuf buf = Unpooled.buffer(str.getBytes().length);
        //buf.writeBytes(str.getBytes("GBK"));
        //channelHandlerContext.writeAndFlush(str);
        ChannelHandler.channels.writeAndFlush(str);
    }

    @Override
    public void channelActive(ChannelHandlerContext channelHandlerContext) throws IOException {
        //当有客户端连接时,将其添加到channelGroup中
        ChannelHandler.channels.add(channelHandlerContext.channel());
        NioSocketChannel channel = (NioSocketChannel) channelHandlerContext.channel();
        System.out.println("链接报告开始 {公众号:bugstack虫洞栈 >获取学习源码}");
        System.out.println("链接报告信息:有一客户端链接到本服务端");
        System.out.println("链接报告IP:" + channel.localAddress().getHostName());
        System.out.println("链接报告Port:" + channel.localAddress().getPort());
        System.out.println("链接报告完毕");
        //通知客户端连接成功
        String dateStr = sdf.format(new Date());
        String str = "通知客户端建立连接成功...." + dateStr + channel.localAddress();
        //ByteBuf buf = Unpooled.buffer(str.getBytes().length);
       // buf.writeBytes(str.getBytes("GBK"));
        ChannelHandler.channels.writeAndFlush(str);
    }

    @Override
    public void channelInactive(ChannelHandlerContext context) {
        System.out.println("断开连接...." + context.channel().localAddress());
        //当有客户端断开连接时,将其从channelGroup中移除
        ChannelHandler.channels.remove(context.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext channelHandlerContext,Throwable throwable){
        channelHandlerContext.close();
        System.out.println("异常信息: \n"+throwable);
    }
}

ChannelHandler 类

public class ChannelHandler {

    public static ChannelGroup channels=
            new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
}

Netty 依赖

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.36.Final</version>
        </dependency>

效果展示

netAssist 工具

下载地址:
https://download.csdn.net/download/echohuangshihuxue/87311946?spm=1001.2014.3001.5503

启动Netty server

启动NettyServer 的main方法即可启动 Netty 服务端。同时 会监控客户端的连接。

打开netAssist 工具

利用netAssist 来模拟客户端的连接。

在这里插入图片描述

在这里插入图片描述

具体的逻辑是MyServerHandler 类。可以参考流程图和代码进行理解和联系。如有疑问,欢迎评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/96794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三十一章 linux-模块的加载过程

第三十一章 linux-模块的加载过程 文章目录第三十一章 linux-模块的加载过程sys_init_modulestruct moduleload_module在用户空间&#xff0c;用insmod这样的命令来向内核空间安装一个内核模块&#xff0c;本节将详细讨论模块加载时的内核行为。当调用“insmod demodev.ko”来安…

通讯录的思路与实现(C语言)

目录 前言 程序的分装 程序的结构 函数实现 通讯录的初始化 通讯录的扩容 将数据保存到本地 增加联系人 显示通讯录所有联系人 目标联系人的检索(根据名称) 目标联系人的检索(根据号码) 检索发展来的函数 删除联系人 查询目标联系人 联系人信息的更改 按名称对通…

Python写个“点球大战”小游戏

大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 看过我Python入门教程的朋友应该会看到其中有提到一个点球小游戏的作业。 在世界杯决赛即将到来之际&#xff0c;我们再来回顾一下这个小游戏。对于刚刚学习编程不久的同学&#xff0c;这是个不错的练手习题&…

(二)RT-Thread入门——线程管理

目录 线程管理 线程管理特点 线程工作机制 线程控制块 线程属性 线程栈 线程状态 线程优先级 时间片 线程入口函数 无限循环模式 顺序执行或有限次循环模式 线程错误码 线程状态切换 线程操作 创建动态线程 删除 初始化静态线程 脱离 获得当前线程 让出…

数据结构基础篇》》用c语言实现复数的八个基本运算

数据结构开讲啦&#xff01;&#xff01;&#xff01;&#x1f388;&#x1f388;&#x1f388; 本专栏包括&#xff1a; 抽象数据类型线性表及其应用栈和队列及其应用串及其应用数组和广义表树、图及其应用存储管理、查找和排序将从简单的抽象数据类型出发&#xff0c;深入浅出…

B-013 缓启动电路设计

缓启动电路设计1 简介2 案例分析2.1 电路说明2.2 原理分析3 电路参数设定说明1 简介 缓启电路的供电是由一个PMOS控制通断的&#xff0c;软启动的设计是让PMOS的导通时间变缓&#xff0c;电路上的做法是在PMOS的栅极和源极之间接一个合适的电容&#xff0c;PMOS的导通时间就会…

Arcgis中创建Python脚本工具

文章目录创建工具步骤第一步&#xff1a;第二步&#xff1a;第三步&#xff1a;定义工具工具箱Toolbox工具类1、__init__2、getParameterInfo3、isLicensed4、updateParameters5、updateMessage6、execute进度条的使用代码相比于自定义工具箱的源脚本和参数定义难以集中管理的缺…

中国专利电子申请网站系统环境配置方法

一、在线平台使用环境要求 支持的操作系统、浏览器、office的版本如下&#xff0c;必须匹配对应的版本&#xff1a; 操作系统&#xff1a;WINDOWS XP、WINDOWS 7、WINDOWS 8 浏览器&#xff1a;IE8、IE9、IE10 文档编辑软件&#xff1a;OFFICE2003、OFFICE2007 强烈推荐使用中…

1. Maven基础

1. Maven简介 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构 提供了一套标准化的构建流程&#xff08;编译&#xff0c;测试&#xff0c;打包&#xff0c;发布……&#xff09; 提供了一套依赖管理机制 1.1…

Allegro快速编辑丝印文字操作指导

Allegro快速编辑丝印文字操作指导 Allegro支持丝印文字的编辑,下面介绍快速编辑丝印文字的两种方法如下 以编辑下方丝印文字为例 方法一: 选择Text edit 命令 点击丝印文字,丝印会被高亮起来 输入需要更改后的文字,如下 右击选择done 文字被更改好了 方法二 选择se…

Function composition

In mathematics, function composition is an operation  ∘  that takes two functions f and g, and produces a function h g  ∘  f such that h(x) g(f(x)). In this operation, the function g is applied to the result of applying the function f to x. That is…

van-uplaoder保存文件到后端,回显后端接口返回的数据

实现功能&#xff1a;在移动端使用van-uploader组件上传图片&#xff0c;然后调用接口保存到后端数据库&#xff0c;提交保存信息成功后&#xff0c;调用另外的接口返回数据用来回显uploaded的文件&#xff0c;&#xff08;一般正常的返回数据的接口是个图片地址&#xff0c;可…

15 CPP函数重载

函数重载的细节&#xff1a; 1 使用重载函数时&#xff0c;如果数据类型不匹配&#xff0c;C尝试使用类型转换与形参进行匹配&#xff0c;如果转换后有多个函数能匹配上&#xff0c;编译将报错。 2 引用可以作为函数重载的条件&#xff0c;但是调用重载函数的 时候&#xff0…

javaSE - 认识字符串(String class),String类里面方法的使用,下半部分

一、字符, 字节与字符串 1.1、字符与字符串之间进行转换 字符串内部包含一个字符数组&#xff0c;String 可以和 char[] 相互转换 将整个字符数组转换成字符串 public static void main(String[] args) {char[] chars {a,b,c,d,e,f,g};String str new String(chars);Sys…

Sulfo-NHS-SS-biotin,CAS:325143-98-4介绍,生物素双硫键琥珀酰亚胺

英文名称&#xff1a;Sulfo-NHS-SS-biotin 化学式&#xff1a;C19H27N4NaO9S4 分子量&#xff1a;606.7 CAS&#xff1a;325143-98-4 纯度&#xff1a;95% 储存条件&#xff1a;-20C 结构式&#xff1a; 简介&#xff1a;磺基NHS SS生物素是一种可切割试剂&#xff0c;用…

【剧前爆米花--爪哇岛寻宝】抽象类和接口(上)——理论及逻辑理解

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于抽象类和接口的文章&#xff0c;在本篇文章中我会介绍其相关的定义和语法&#xff0c;并且揭示接口和抽象类的运行逻辑&#xff0c;提高对面对象编程的理解。 目录 抽象…

吴恩达week6 ~批量梯度下降 指数加权平均 动量梯度下降 学习率衰减 Adam

文章目录前言一、小批量梯度下降 mini-batch1、batch gradient descent2、stochastic gradient descent3、mini-batch gradient descent二、指数加权平均1.什么是指数加权平均2、理解指数加权平均3、与普通求平均值的区别4、指数加权平均的偏差修正三、gradient descent with m…

Allegro批量替换过孔类型操作指导

Allegro批量替换过孔类型操作指导 Allegro支持批量替换过孔类型,具体操作如下 例如需要把这些VIA10的过孔全部替换成VIA8的过孔 选择菜单上面的Tool-padstack-Group edit 右击选择temp Group 选中需要替换的过孔 选完之后右击选择complete 弹出Padstack Map窗口,modify…

java中多线程、并发、并行、线程与进程、线程调度、创建线程的方式

多线程&#xff1a; 多线程比单线程快&#xff0c;前面简单介绍过&#xff1a;集合如果是不安全的&#xff0c;那么它就是多线程的&#xff0c;了解多线程之前&#xff0c;先了解什么是并发和并行。 并发&#xff1a;指两个或多个事件在同一个时间段内发生。 并行&#xff1…