精华内容
下载资源
问答
  • netty 代理服务器

    2018-03-06 00:07:54
    netty开发的http代理服务器,含三个实例,都可正常运行
  • 简单实现了netty客户端与服务器的通信
  • netty游戏服务器核心

    2017-06-28 14:41:59
    自己基于netty4写的游戏服务器核心层,可以拿来学习
  • java服务器如何搭建Netty服务器,如何处理通信上出现问题,如何处理粘包。
  • Netty(六) Netty Http服务器例子

    千次阅读 2018-05-28 10:38:19
    Http服务器 netty学习目录 一、Netty(一) NIO例子 二、Netty(二) netty服务端 三、Netty(三) Netty客户端+服务端 ...六、Netty(六) Netty Http 服务器例子 package com.zqw.netty.http; import io....

    Http服务器

    netty学习目录
    一、Netty(一) NIO例子
    二、Netty(二) netty服务端
    三、Netty(三) Netty客户端+服务端
    四、Netty(四) 简化版Netty源码
    五、Netty(五)Netty5.x服务端
    六、Netty(六) Netty Http 服务器例子
    七、Netty(七) Netty服务端+客户端代码
    八、Netty(八) Netty多客户端连接例子
    九、Netty(九) Netty会话清除
    十、Netty(十) Netty自定义编码器解码器
    十一、Netty(十一) Netty对象传输

    package com.zqw.netty.http;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.codec.http.HttpObjectAggregator;
    import io.netty.handler.codec.http.HttpRequestDecoder;
    import io.netty.handler.codec.http.HttpRequestEncoder;
    import io.netty.handler.codec.http.HttpResponseEncoder;
    
    /**
     * @Author: zhuquanwen
     * @Description:
     * @Date: 2018/5/28 9:53
     * @Modified:
     **/
    public class Server {
        public static void main(String[] args) {
            ServerBootstrap bootstrap = new ServerBootstrap();
            EventLoopGroup boss = new NioEventLoopGroup();
            EventLoopGroup worker = new NioEventLoopGroup();
            try{
                bootstrap.group(boss, worker);
                bootstrap.option(ChannelOption.SO_BACKLOG, 2048);
                bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
                bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
                bootstrap.channel(NioServerSocketChannel.class);
                bootstrap.childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel ch) throws Exception {
                        ch.pipeline().addLast(new HttpRequestDecoder());
                        ch.pipeline().addLast(new HttpResponseEncoder());
                        ch.pipeline().addLast(new HttpObjectAggregator(1024*1024));
                        ch.pipeline().addLast(new ServerHandler());
                    }
                });
                ChannelFuture future = bootstrap.bind(7777);
                System.out.println("http server start success");
                future.channel().closeFuture().sync();
    
            }catch (Exception e){
                e.printStackTrace();
            } finally {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }
    }
    
    package com.zqw.netty.http;
    
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandler;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelHandlerInvoker;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.*;
    import io.netty.util.concurrent.EventExecutorGroup;
    
    /**
     * @Author: zhuquanwen
     * @Description:
     * @Date: 2018/5/28 9:59
     * @Modified:
     **/
    public class ServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
        @Override
        protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
            DefaultFullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,HttpResponseStatus.OK,Unpooled.wrappedBuffer("test".getBytes()));
            HttpHeaders headers = response.headers();
            headers.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN +";charset=utf-8");
            headers.add(HttpHeaderNames.CONTENT_LENGTH, ""+response.content().readableBytes());
            headers.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            ctx.writeAndFlush(response);
        }
    }
    
    package com.zqw.netty.http;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.codec.http.HttpObjectAggregator;
    import io.netty.handler.codec.http.HttpRequestDecoder;
    import io.netty.handler.codec.http.HttpRequestEncoder;
    import io.netty.handler.codec.http.HttpResponseEncoder;
    
    /**
     * @Author: zhuquanwen
     * @Description:
     * @Date: 2018/5/28 9:53
     * @Modified:
     **/
    public class Server {
        public static void main(String[] args) {
            ServerBootstrap bootstrap = new ServerBootstrap();
            EventLoopGroup boss = new NioEventLoopGroup();
            EventLoopGroup worker = new NioEventLoopGroup();
            try{
                bootstrap.group(boss, worker);
                bootstrap.option(ChannelOption.SO_BACKLOG, 2048);
                bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
                bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
                bootstrap.channel(NioServerSocketChannel.class);
                bootstrap.childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel ch) throws Exception {
                        ch.pipeline().addLast(new HttpRequestDecoder());
                        ch.pipeline().addLast(new HttpResponseEncoder());
                        ch.pipeline().addLast(new HttpObjectAggregator(1024*1024));
                        ch.pipeline().addLast(new ServerHandler());
                    }
                });
                ChannelFuture future = bootstrap.bind(7777);
                System.out.println("http server start success");
                future.channel().closeFuture().sync();
    
            }catch (Exception e){
                e.printStackTrace();
            } finally {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }
    }
    
    展开全文
  • netty 服务器端主动发消息给客户端 内容精选换一换客户在云容器引擎上搭建服务为手机应用订阅信息。首先客户端会向部署在CCE集群上的服务端(redis)发起请求,成功订阅信息服务。后继服务端侧会定时推送订阅的消息给...

    netty 服务器端主动发消息给客户端 内容精选

    换一换

    c8a5a5028d2cabfeeee0907ef5119e7e.png

    客户在云容器引擎上搭建服务为手机应用订阅信息。首先客户端会向部署在CCE集群上的服务端(redis)发起请求,成功订阅信息服务。后继服务端侧会定时推送订阅的消息给客户端。服务端部署后,第一次订阅信息通信正常,但是10分钟内没有数据通信,客户端就接收不到订阅信息了。客户端第一次向服务端建立通信链接的时候(订阅),会主动开放对服务端的通信权限

    设备接入到物联网平台后,便可与物联网平台进行通信。设备通过自定义Topic或产品模型方式将数据上报到平台,在控制台设置后,通过订阅推送的方式,将设备生命周期变更、设备属性上报、设备消息上报、设备消息状态变更、设备状态变更、批量任务状态变更等消息推送到您指定的服务器。当前华为物联网平台支持HTTP/HTTPS和AMQP两种订阅方式:HTTP

    netty 服务器端主动发消息给客户端 相关内容

    ELB的常见异常返回码有400、403、502、504等。若遇到这些返回码建议您先直接访问后端云服务器,查看是否是后端云服务器的异常。若后端云服务器响应正常,请参考表1排查处理。如果仍无法解决,请联系客服人员继续排查。

    Netty是一个非阻塞I/O客户端-服务器框架,主要用于开发Java网络应用程序,如:协议服务器和客户端。Netty包括了反应器编程模式的实现。Netty最初由JBoss开发,现在由Netty项目社区开发和维护。除了作为异步网络应用程序框架,Netty还包括了对HTTP、HTTP2、DNS及其他协议的支持,涵盖了在Servlet容器内运行

    netty 服务器端主动发消息给客户端 更多内容

    5a6f55482f6b3f19420161bd3dfbba6a.png

    Redis实例的发布订阅功能详细信息参见Pub/Sub,使用Redis发布订阅功能时有如下事项请注意:客户端需要及时消费和处理消息。客户端订阅了channel之后,如果接收消息不及时,可能导致DCS实例消息堆积,当达到消息堆积阈值(默认值为32MB),或者达到某种程度(默认8MB)一段时间(默认为1分钟)后,服务器端会自动断开该客户端连接

    f3b8b8d84706868f201fb0c4780edbab.png

    由于WebSocket是全双工的,因此响应就是从服务器端发送给客户端的消息,但也并不是所有的请求信息都有一条对应的响应。服务器端收到“开始识别”请求时,会给出如下响应消息,以json字符串形式放置在text message中。状态码请参见状态码。错误码请参见错误码。

    55a2638139d68369d49b3058cd5d88e8.png

    HTTP/2是HTTP超文本传输协议的最新版本,于2015年5月份正式发布,HTTP/2之前有HTTP1.0和HTTP1.1两个版本。各主流浏览器,如Chrome、Firefox、Safari及IE11等均已支持HTTP/2协议。目前,http://url只能使用HTTP1.x版本协议,https://url支持HTTP/2版本的使用。H

    9548b768b78243d473da1b2758db3f2b.png

    设备接入到物联网平台后,便可与物联网平台进行通信。设备通过自定义Topic或产品模型方式将数据上报到平台,在控制台设置后,通过订阅推送的方式,将设备生命周期变更、设备属性上报、设备消息上报、设备消息状态变更、设备状态变更、批量任务状态变更等消息推送到您指定的服务器。当前华为物联网平台支持HTTP/HTTPS和AMQP两种订阅方式:HTTP

    c0e51685ecf1c455eed0daf868911dc9.png

    一个响应消息通常由三部分组成:状态行、响应报头、响应正文。响应消息格式如表1所示。HTTP-Version Status-Code Reason-Phrase CRLF其中:HTTP-Version表示服务器HTTP协议的版本号Status-Code表示服务器发回的响应状态代码Reason-Phrase表示状态代码的文本描述。状态代码有三

    f2c4fc7c94b8a6968e9bfbe258188211.png

    本节提供API API和SDK的定义要求。REST中定义工程对外提供的服务。HTTP动词:常用的HTTP动词如下(括号里是对应的SQL命令):GET(SELECT):从服务器取出一项或多项资源。POST(CREATE):在服务器新建一个资源。PUT(UPDATE):客户端提供改变后的完整资源,在服务器更新资源。PATCH(UPDATE):

    e8856eb4a33744e9e363326f14bf7b97.png

    使用SSH方式登录CentOS 6.5操作系统的弹性云服务器时,过一段时间就会自动断开连接。本节操作介绍如何保持SSH会话持续连接不断开该文档适用于CentOS/EulerOS系统。本节操作涉及重启sshd服务,会造成sshd断开。编辑/etc/ssh/sshd_config文件设置心跳,保持连接。编辑/etc/ssh/sshd_conf

    784b2dc537fb8677eac9c3453eafe288.png

    如果客户端或JDBC/ODBC应用程序要使用SSL连接方式,用户必须在客户端或应用程序代码中配置相关的SSL连接参数。GaussDB(DWS) 管理控制台提供了客户端所需的SSL证书,该SSL证书包含了客户端所需的默认证书、私钥、根证书以及私钥密码加密文件。请将该SSL证书下载到客户端所在的主机上,然后在客户端中指定证书所在的路径。使用默

    91fba63c5e17e5f0e99d0f8174c4b31b.png

    修改系统时间后服务器网卡出现感叹号,无法连接网络。该文档适用于CentOS 7、EulerOS,并使用DHCP协议获取IP场景。DHCP租约通常默认为24小时,具体以实际场景为例。DHCP会话过程:DHCP典型会话过程包括:DHCP发现、DHCP提供、DHCP请求、DHCP确认,如图1所示DHCP发现(DISCOVER)客户在物理子网上发

    展开全文
  • 刚学netty ,写了一个基于netty服务器客户端收发消息代码,功能非常简单,服务器每3秒向服务器发消息,服务器再把消息反给你。简单收1分,希望大家谅解。
  • netty服务器son解析

    2021-08-23 15:33:05
    netty服务器son解析
  • microboot是基于Netty开发的一个HTTP服务框架,本身提供http服务器功能,jar包方式启动,使用方式与架构与Spring MVC极为相似,microboot没有遵循java web规范,非常轻量级,并且高效。 微启动能做什么 microboot...
  • 工程背景:springboot + netty(如果单纯的springboot同样适用) 工程打包,包括:工程IP的更换,数据库IP地址更换。 工程上传到指定服务器,数据库导入服务器数据库管理系统。 通过命令运行服务器中上传的工程包。 ...

    部署前猜想

    1. 工程背景:springboot + netty(如果单纯的springboot同样适用)
    2. 工程打包,包括:工程IP的更换,数据库IP地址更换。
    3. 工程上传到指定服务器,数据库导入服务器数据库管理系统。
    4. 通过命令运行服务器中上传的工程包。
    5. 测试是否部署成功:controller、TCP两方验证。
    6. 流程:本地工程文件上传到服务器,然后通过xx方法启动,然后能正常访问。

    部署实战

    一、 本地打包测试

    		(开发环境、打包工具、只需上网搜索对应方法即可,下图是idea通过插件打包)
    

    1)首先:原工程什么都不改,直接通过idea右侧的maven,最好先执行下图1清除一下工程中target文件(非必需)。找到package打包工具(可用其他方法)。执行完打包后会在工程target中生成XX.jar文件。 --此过程可能出现错误,按照类型解决即可。

    在这里插入图片描述

    2)其次:把生成的XX.jar文件随便放到一个地方,然后执行 java -jar XX.jar 命令,如果能正常启动且能访问到工程资源标志打包成功。 --此过程可能出现错误,按照类型解决即可;

    总结:把工程打包成jar包,通过 java -jar XX.jar运行,看是否和在开发工具中效果一样。效果一样说明打包逻辑没有问题,可以进入下一步。

    二、正式打包

    不同的是无非是地址的更换(通过全局替换快捷键完成:127.0.0.1或localhost–>XX IP),一个是私有地址,一个是公有地址,你可以浅显的认为我买了服务器就是买了一个公有IP(只是为了站的更高让别人能够看见我);

    三、 MySQL文件

    导出数据库管理系统中对应的数据库SQL文件(如navicat for mysql -->找到数据库,点击右键转储为SQL文件);

    四、上传打出的jar包和SQL文件到服务器

    1)工具说明:
    Xshell: 看成连接服务器的一个工具
    Xftp:看成本地文件上传到服务器的一个工具
    只要能完成需求什么工具均可。

    使用一:点击下图中1新建会话,名称随意,IP即你需要连接的服务器IP,其他默认然后确定,这时就会提示让你输入用户名和密码,输入完成后进入服务器Linux系统。

    在这里插入图片描述

    使用二:下图为Xshell的工具栏,找到文件传输点击(或者直接启动Xftp软件也可):
    在这里插入图片描述

    下图为Xftp传输界面,直接通过windwos中快捷键Ctrl + c等完成本地文件夹到服务器文件夹即可。

    在这里插入图片描述
    2)资源上传:XX.jar(工程打出的包)、XX.sql(工程所需的SQL文件),通过上面工具即可完成。

    五、资源文件使用

    XX.jar包:
    1)启动:java -jar XXX.jar
    如果报错,那就根据错误找解决方法即可,比如:此处我出现了端口错误,因为本地工程用到的是8888端口,那么按照逻辑去开放端口即可(网上搜索Linux开放端口方法),如果你用到了其他的端口可同理开放。
    2)开放端口
    1 查询已开放端口:firewall-cmd --list-ports
    2 开启端口: firewall-cmd --zone=public --add-port=8888/tcp --permanent
    3 检查是否开启成功:firewall-cmd --list-ports,通常不成功,因为需要重启防火墙。
    4 重启防火墙相关命令:systemctl start/stop/status/reload firewalld 开启/关闭/状态/重启 防火墙
    5 再次检查端口是否开启成功: firewall-cmd --list-ports
    6 登陆阿里云,配置需要开放的端口。–否则会出现项目正常启动但是本地无法访问的情况。

    XX.sql文件
    1) 启动数据库
    1 查看MySQL状态:service mysql status
    2 MySQL启动命令:service mysql start
    3 启动后连接数据库: mysql -u 数据库名字 -p
    4 输入密码,按照安装mysql时设置的密码操作即可。

    在这里插入图片描述

    2) 导入XX.sql文件到数据库管理系统

    ​ 1 登陆数据库后,创建数据库:create database xxx;
    这里的xxx要和本地导出的SQL文件名字相同(Linux中SQL命令末尾以分号结尾)。

    在这里插入图片描述

    ​ 2 切换到新建好的数据库:user xxx;

    ​ 3 导入SQL文件到数据库管理系统:source 文件位置;如在步骤四中通过资源上传步骤把SQL文件存放在服务器 /opt 文件下,那此处命令对应:source /opt/XX.sql 即可完成SQL文件导入到服务器数据库中。

    六、测试
    1)测试启动:通过java -jar XXX.jar 启动命令,启动上传到服务器的jar工程。1599210057957)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200904152438437.png)]

    2)测试本地访问:通过:IP:端口号/工程路径 如此处:ip:8888/bms/swagger-ui.html。

    在这里插入图片描述

    3)测试本地TCP连接:通过上步已经完成了基本的部署和调试,下图是netty的TCP调试,如果只是springboot不需要此步。
    在这里插入图片描述

    总结:部署前的猜想,逻辑上基本正确,分为:项目打包、SQL文件导出、项目和SQL文件导入到服务器中、通过命令在服务器运行即可,在这个过程中会有工具使用如怎么连接服务器、怎么上传文件等,同时需要掌握Linux相关命令(前提是你大概知道这步需要做什么,然后就搜对应的指令),当然在部署过程中会遇到不同类型的问题,这些问题基本都是配置上的问题,按照错误提示进行修改即可,实在不行就去网上借鉴一下别人的经验。

    展开全文
  • 一、 Netty 模型代码解析 、 二、 Netty 案例服务器端代码 、 三、 Netty 案例客户端代码 、 四、 Netty 案例运行 、





    一、 Netty 模型代码解析



    1 . 线程池 NioEventLoopGroup :


    ① NioEventLoopGroup 线程池使用场景 : Netty 模型中的 BossGroup 和 WorkerGroup 都是 NioEventLoopGroup 类型的线程池 ;

    ② NioEventLoopGroup 默认线程个数 : 系统默认每个线程池中的 NioEventLoop 线程数是 CPU 核数 × \times × 2 , 下面的代码可以获取运行 Netty 程序的设备的 CPU 核数 ;

    // 获取设备的 CPU 核数
    NettyRuntime.availableProcessors()
    

    ③ 指定 NioEventLoopGroup 线程个数 : 如果不想使用 Netty 线程池的默认线程个数 , 可以在 NioEventLoopGroup 构造函数中子星设定线程数 ;

    // BossGroup 线程池 : 负责客户端的连接
    // 指定线程个数 : 客户端个数很少, 不用很多线程维护, 这里指定线程池中线程个数为 1
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    


    2 . NioEventLoopGroup 线程池线程分配 :


    以客户端连接完成后 , 数据读写场景举例 ;

    在 双核 CPU 的服务器上 , NioEventLoopGroup 默认有 4 4 4 个线程 ; 按照顺序循环分配 , 为第 n n n 个客户端分配第 n % 4 n \% 4 n%4 个 NioEventLoop 线程 ;

    • 客户端 0 0 0 与服务器进行数据交互在 NioEventLoop 0 0 0 线程中 ;
    • 客户端 1 1 1 与服务器进行数据交互在 NioEventLoop 1 1 1 线程中 ;
    • 客户端 2 2 2 与服务器进行数据交互在 NioEventLoop 2 2 2 线程中 ;
    • 客户端 3 3 3 与服务器进行数据交互在 NioEventLoop 3 3 3 线程中 ;
    • 客户端 4 4 4 与服务器进行数据交互在 NioEventLoop 0 0 0 线程中 ;
    • 客户端 5 5 5 与服务器进行数据交互在 NioEventLoop 1 1 1 线程中 ;
    • 客户端 6 6 6 与服务器进行数据交互在 NioEventLoop 2 2 2 线程中 ;
    • 客户端 7 7 7 与服务器进行数据交互在 NioEventLoop 3 3 3 线程中 ;


    3 . NioEventLoopGroup 线程池封装内容 :


    ① NioEventLoopGroup 中的若干个 NioEventLoop 线程都封装在 children 中 , 线程个数是 CPU 核数 2 倍 ;

    ② 每个 NioEventLoop 线程中封装了如下内容 :

    • 选择器 ( Selector ) , 用于监听客户端的读写 IO 事件 ;
    • 任务队列 ( taskQueue ) , 用于存储事件对应的业务逻辑任务 ;
    • 线程执行器 ( executor ) , 用于执行线程 ;


    4 . ChannelHandlerContext 通道处理者上下文对象封装内容 :


    ① 用户自定义的 处理者 ( Handler ) , 这里指的是 服务器端的 ServerHandr ( 自定义 ) , 客户端的 ClientHandler ( 自定义 ) ;

    ② 管道 ( ChannelPipeline ) : 其本质是双向链表 , 该 ChannelHandlerContext 可以获取该链表的前一个 ( prev ) , 后一个管道对象 ( next ) ;

    ③ 管道 与 通道 :

    • 二者都可以通过 通道处理者上下文 ( ChannelHandlerContext ) 获取 ;
    • 管道 与 通道 都可以互相从对方获取 ;
    Channel channel = ctx.channel();
    ChannelPipeline pipeline = ctx.pipeline();
    channel = pipeline.channel();
    pipeline = channel.pipeline();
    

    ④ 管道 ( Pipeline ) 与 通道 ( Channel ) 关联 : 通过管道可以获取通道 , 通过通道也可以获取其对应的管道 ;



    5 . 处理者 ( Handler ) :


    ① 设置 Handler : 给 WorkerGroup 线程池中的 EventLoop 线程对应的管道设置 处理器 ( Handler ) ;

    ② 自定义 Handler : 一般这个 Handler 都是用户自定义的类 , 继承 ChannelInboundHandlerAdapter 类 ;

    ③ 运行机制 : 在 BossGroup 中连接客户端成功后 , 将 NioSocketChannel 注册给 WorkerGroup 中的 EventLoop 中的 选择器 ( Selector ) , 如果监听到客户端数据 IO 事件 , 就会调用 管道 ( Pipeline ) 处理该事件 , 管道 ( Pipeline ) 中调用 处理器 ( Handler ) 处理相应的事件 , 该 处理器 ( Handler ) 可以是 Netty 提供的 , 也可以是开发者自定义的 ;


    特别注意 : 自定义 Handler 中 , 重写的 ChannelInboundHandlerAdapter 方法 , 将 super() 语句都删除 ;





    二、 Netty 案例服务器端代码




    1 . 服务器主程序

    package kim.hsl.netty;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    /**
     * Netty 案例服务器端
     */
    public class Server {
        public static void main(String[] args) {
    
            // 1. 创建 BossGroup 线程池 和 WorkerGroup 线程池, 其中维护 NioEventLoop 线程
            //     NioEventLoop 线程中执行无限循环操作
    
            // BossGroup 线程池 : 负责客户端的连接
            // 指定线程个数 : 客户端个数很少, 不用很多线程维护, 这里指定线程池中线程个数为 1
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            // WorkerGroup 线程池 : 负责客户端连接的数据读写
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            // 2. 服务器启动对象, 需要为该对象配置各种参数
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup) // 设置 主从 线程组 , 分别对应 主 Reactor 和 从 Reactor
                    .channel(NioServerSocketChannel.class)  // 设置 NIO 网络套接字通道类型
                    .option(ChannelOption.SO_BACKLOG, 128)  // 设置线程队列维护的连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE, true)  // 设置连接状态行为, 保持连接状态
                    .childHandler(  // 为 WorkerGroup 线程池对应的 NioEventLoop 设置对应的事件 处理器 Handler
                            new ChannelInitializer<SocketChannel>() {// 创建通道初始化对象
                                @Override
                                protected void initChannel(SocketChannel ch) throws Exception {
                                    // 为 管道 Pipeline 设置处理器 Hanedler
                                    ch.pipeline().addLast(new ServerHandr());
                                }
                            }
                    );
            System.out.println("服务器准备完毕 ...");
    
            ChannelFuture cf = null;
            try {
                // 绑定本地端口, 进行同步操作 , 并返回 ChannelFuture
                cf = bootstrap.bind(8888).sync();
                System.out.println("服务器开始监听 8888 端口 ...");
                // 关闭通道 , 开始监听操作
                cf.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 出现异常后, 优雅的关闭
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
    
        }
    }
    


    2 . 服务器自定义 Handler 处理者

    package kim.hsl.netty;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.channel.ChannelPipeline;
    import io.netty.util.CharsetUtil;
    
    /**
     * Handler 处理者, 是 NioEventLoop 线程中处理业务逻辑的类
     *
     * 继承 : 该业务逻辑处理者 ( Handler ) 必须继承 Netty 中的 ChannelInboundHandlerAdapter 类
     * 才可以设置给 NioEventLoop 线程
     *
     * 规范 : 该 Handler 类中需要按照业务逻辑处理规范进行开发
     */
    public class ServerHandr extends ChannelInboundHandlerAdapter {
    
        /**
         * 读取数据 : 在服务器端读取客户端发送的数据
         * @param ctx
         *      通道处理者上下文对象 : 封装了 管道 ( Pipeline ) , 通道 ( Channel ), 客户端地址信息
         *      管道 ( Pipeline ) : 注重业务逻辑处理 , 可以关联很多 Handler
         *      通道 ( Channel ) : 注重数据读写
         * @param msg
         *      客户端上传的数据
         * @throws Exception
         */
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            // 查看 ChannelHandlerContext 中封装的内容
            System.out.println("channelRead : ChannelHandlerContext ctx = " + ctx);
    
            // 将客户端上传的数据转为 ByteBuffer
            // 这里注意该类是 Netty 中的 io.netty.buffer.ByteBuf 类
            // 不是 NIO 中的 ByteBuffer
            // io.netty.buffer.ByteBuf 性能高于 java.nio.ByteBuffer
            ByteBuf byteBuf = (ByteBuf) msg;
            // 将 ByteBuf 缓冲区数据转为字符串, 打印出来
            System.out.println(ctx.channel().remoteAddress() + " 接收到客户端发送的数据 : " + 
            	byteBuf.toString(CharsetUtil.UTF_8));
        }
    
        /**
         * 服务器端读取数据完毕后回调的方法
         * @param ctx
         *      通道处理者上下文对象 : 封装了 管道 ( Pipeline ) , 通道 ( Channel ), 客户端地址信息
         *      *      管道 ( Pipeline ) : 注重业务逻辑处理 , 可以关联很多 Handler
         *      *      通道 ( Channel ) : 注重数据读写
         * @throws Exception
         */
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            // 数据编码 : 将字符串编码, 存储到 io.netty.buffer.ByteBuf 缓冲区中
            ByteBuf byteBuf = Unpooled.copiedBuffer("Hello Client", CharsetUtil.UTF_8);
    
            // 写出并刷新操作 : 写出数据到通道的缓冲区 ( write ), 并执行刷新操作 ( flush )
            ctx.writeAndFlush(byteBuf);
        }
    
        /**
         * 异常处理 , 上面的方法中都抛出了 Exception 异常, 在该方法中进行异常处理
         * @param ctx
         * @param cause
         * @throws Exception
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            System.out.println("通道异常, 关闭通道");
            //如果出现异常, 就关闭该通道
            ctx.close();
        }
    }
    




    三、 Netty 案例客户端代码




    1 . 客户端主程序

    package kim.hsl.netty;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    public class Client {
        public static void main(String[] args) {
            // 客户端只需要一个 时间循环组 , 即 NioEventLoopGroup 线程池
            EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    
            // 客户端启动对象
            Bootstrap bootstrap = new Bootstrap();
            // 设置相关参数
            bootstrap.group(eventLoopGroup)     // 设置客户端的线程池
                    .channel(NioSocketChannel.class)    // 设置客户端网络套接字通道类型
                    .handler(   // 设置客户端的线程池对应的 NioEventLoop 设置对应的事件处理器 Handler
                            new ChannelInitializer<SocketChannel>() {
                                @Override
                                protected void initChannel(SocketChannel ch) throws Exception {
                                    ch.pipeline().addLast(new ClientHandr());
                                }
                            }
                    );
    
            try {
                // 开始连接服务器, 并进行同步操作
                // ChannelFuture 类分析 , Netty 异步模型
                // sync 作用是该方法不会再次阻塞
                ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8888).sync();
                System.out.println("客户端连接服务器成功 ...");
    
                // 关闭通道, 开始监听
                channelFuture.channel().closeFuture().sync();
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                // 优雅的关闭
                eventLoopGroup.shutdownGracefully();
            }
        }
    }
    


    2 . 客户端自定义 Handler 处理者

    package kim.hsl.netty;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.util.CharsetUtil;
    
    /**
     * Handler 处理者, 是 NioEventLoop 线程中处理业务逻辑的类
     *
     * 继承 : 该业务逻辑处理者 ( Handler ) 必须继承 Netty 中的 ChannelInboundHandlerAdapter 类
     * 才可以设置给 NioEventLoop 线程
     *
     * 规范 : 该 Handler 类中需要按照业务逻辑处理规范进行开发
     */
    public class ClientHandr extends ChannelInboundHandlerAdapter {
    
        /**
         * 通道就绪后触发该方法
         * @param ctx
         * @throws Exception
         */
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            // 查看 ChannelHandlerContext 中封装的内容
            System.out.println("channelActive : ChannelHandlerContext ctx = " + ctx);
    
            // 数据编码 : 将字符串编码, 存储到 io.netty.buffer.ByteBuf 缓冲区中
            ByteBuf byteBuf = Unpooled.copiedBuffer("Hello Server", CharsetUtil.UTF_8);
    
            // 写出并刷新操作 : 写出数据到通道的缓冲区 ( write ), 并执行刷新操作 ( flush )
            ctx.writeAndFlush(byteBuf);
            System.out.println("客户端向服务器端发送 Hello Server 成功");
        }
    
        /**
         * 读取数据 : 在服务器端读取客户端发送的数据
         * @param ctx
         *      通道处理者上下文对象 : 封装了 管道 ( Pipeline ) , 通道 ( Channel ), 客户端地址信息
         *      管道 ( Pipeline ) : 注重业务逻辑处理 , 可以关联很多 Handler
         *      通道 ( Channel ) : 注重数据读写
         * @param msg
         *      服务器返回的数据
         * @throws Exception
         */
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            // 查看 ChannelHandlerContext 中封装的内容
            System.out.println("channelRead : ChannelHandlerContext ctx = " + ctx);
    
            // 将服务器下发的数据转为 ByteBuffer
            // 这里注意该类是 Netty 中的 io.netty.buffer.ByteBuf 类
            // 不是 NIO 中的 ByteBuffer
            // io.netty.buffer.ByteBuf 性能高于 java.nio.ByteBuffer
            ByteBuf byteBuf = (ByteBuf) msg;
            // 将 ByteBuf 缓冲区数据转为字符串, 打印出来
            System.out.println(ctx.channel().remoteAddress() + " 服务器返回的数据 : " + 
            	byteBuf.toString(CharsetUtil.UTF_8));
        }
    
        /**
         * 异常处理 , 上面的方法中都抛出了 Exception 异常, 在该方法中进行异常处理
         * @param ctx
         * @param cause
         * @throws Exception
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            System.out.println("通道异常, 关闭通道");
            //如果出现异常, 就关闭该通道
            ctx.close();
        }
    }
    




    四、 Netty 案例运行



    1 . 运行服务器端 : 服务器启动 , 监听 8888 端口 ;

    在这里插入图片描述

    2 . 运行客户端 : 客户端连接服务器的 8888 端口 , 并向服务器端写出 Hello Server 字符串 , 之后便接到服务器端回送的 Hello Client 字符串信息 ;

    在这里插入图片描述

    3 . 查看客户端 : 服务器端接收到客户端信息 , 向客户端写出 Hello Client 字符串 ;

    在这里插入图片描述

    展开全文
  • Netty_Android ...采用netty-4.1.16.Final 于服务器保持长连接进行通讯 主要思路为: 开启一个service 初始化Netty连接 service 类 private NetworkReceiver receiver; public static...
  • netty聊天服务器搭建

    2018-01-24 11:58:05
    因此,Netty的ServerBootstrap方法提供了channel方法用于指定服务端Channel的类型。Netty通过工厂类,利用反射创建NioServerSocketChannel对象。 源码 /** * The {@link Class} which is used to create ...
  • netty 实现 服务器 客户端通信

    万次阅读 2016-09-05 18:35:03
    客户端——服务器连接 先啰嗦两句,如果你还不知道Netty是做什么的能做什么。那可以先简单的搜索了解一下。我只能说Netty是一个NIO的框架,可以用于开发分布式的Java程序。具体能做什么,各位可以尽量发挥想象。...
  • Netty服务器与客户端

    2017-02-17 15:25:11
    Netty服务器与客户端
  • netty服务器通讯说明: 服务器条件NETTY框架编程: 服务器IP:192.168.2.106 端口8810 数据传输的方式:从串口接收到一条完整的协议数据,计算出数据字节长度,打包成HtAlingProtocol类,并发送给服务器; package ...
  • Dubbo-Zookeeper-Netty-SpringMVC, 使用dubbo注册服务,netty服务器,springmvc提供restful接口
  • netty游戏服务器搭建之客户端

    千次阅读 2016-12-07 15:18:31
    由于本人没有游戏开发经验,所以用java模拟了一下游戏客户端 ...public class NettyClient {  /*  * 服务器端口号  */  private int port;  /*  * 服务器IP  */  private String host;  publi
  • Netty游戏服务器开发——利用Channel绑定机制 共享...首先我们需要明白一些概念,我们所玩的网络游戏的服务器是一台大规模的收发兼处理工厂,与客户端交互的数据流如同一个个快递。 Netty的NIO机制保证了服务器与每
  • 基于tcp通讯,涉及java的netty服务器的推送功能和c++socket的封装以及protobuf在java和c++中的使用。
  • 本人写的基于netty服务器端通讯框架,报文格式为【int的长度+json格式的字符串】,json格式类似于{cmd:1,data:{}},通过cmd的表示识别controller,仅需在spring配置中配置controller即可,线程池大小和编码格式可在...
  • 实例要求 Http协议是无状态的, 浏览器和服务器间的请求响应一次,下一次会重新创建连接. 要求:实现基于webSocket的长连接的全双工的交互改变Http协议多次请求的...Netty 把HTTP改成WebSocket长连接主要是依靠We...
  • 现在用Netty写一个服务器Server,服务器端绑定本地端口80等待连接,当有客户端Socket连接过来后,就发送字符串“hello,world!”给客户端。客户端连接服务器,连接成功则读取字符串并打印出来,然后关闭socket连接...
  • LineBasedFrameDecoder是回车换行解码器,如果用户发送的消息以回车换行符作为消息结束的标识,则可以直接使用Netty的LineBasedFrameDecoder对消息进行解码,只需要在初始化Netty服务端或者客户端时将...
  • Netty游戏服务器搭建之服务端

    千次阅读 2016-12-07 15:08:57
    一直从事的java web方面的开发,最近想去深圳了,据说那里做游戏服务的很多,就学习一下nio框架netty。 一、 java NIO简介 nio是java New IO的简称,在jdk1.4里提供的新api。Sun官方标榜的特性如下:  为所有的...
  • netty服务器开发

    2015-12-29 13:32:50
    netty nio 长连接 基于NIO非阻塞特性构建高性能、异步和高可靠性的底层通信框架。
  • 在分布式游戏服务器系统中,消息处理队列主要解决问题就是解耦系统中的业务,使得每个系统看起来功能比较单一,而且解决一些全服数据共享等问题。 通常我们知道kafka是作为消息队列比较火的一种方式,其实还有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,416
精华内容 22,566
关键字:

netty是服务器