精华内容
下载资源
问答
  • netty学习(一),搭建netty服务端

    万次阅读 2018-12-23 19:54:48
    使用netty搭建服务端netty服务至少要有两个部分: 1.ChannelHandler-该组建实现了服务器对从客户端接受数据的处理,即业务逻辑 2.引导-配置服务器启动。 ChannelHandler仅仅是一个接口,继承他的有...

    使用netty搭建服务端:

    netty服务至少要有两个部分:

    1.ChannelHandler-该组建实现了服务器对从客户端接受数据的处理,即业务逻辑

    2.引导-配置服务器启动。

    ChannelHandler仅仅是一个接口,继承他的有ChannelInboundHandler和ChannelOutboundHandler,分别是进站和出站事件的响应。

    由于服务器接收消息是进站事件,我们暂时只实现一个简单的进站Handler。

    先来编写一个入站的事件相应:

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandler;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    
    @ChannelHandler.Sharable
    public class FirstHandler extends SimpleChannelInboundHandler<String> {
    
        protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
            ByteBuf buf = Unpooled.buffer();
            System.out.println("receive message " + s);
            ctx.writeAndFlush(buf.writeBytes("first reply".getBytes()));
        }
    
       @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ByteBuf buf = Unpooled.buffer();
            ctx.writeAndFlush(buf.writeBytes("this is server".getBytes()));
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.channel().close();
        }
    }

    入站的Handler我们继承了SimpleChannelInboundHandler,它继承于ChannelInboundHandlerAdapter,在消息入站的实现上,自动为我们做了内存的释放。

    对上面代码进行一个简单的说明,channelRead0是当有入站消息的时候对触发的方法,并且触发后,调ChannelHandlerContext的fireChannelRead的方法,会沿着当前的Handler向出站的方向流动,在netty服务器配置引导的时候,会在管道上绑Handler,并且加入ChannelHandlerContext,ChannelHandlerContext和Handler一一对应。当调用ctx.writeAndFlush时,它会沿着当前方向寻找同样是出站方向的Handler,然后进行处理。

    配置引导,启动服务:

    import io.netty.bootstrap.ServerBootstrap;
    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.NioServerSocketChannel;
    
    import java.util.concurrent.TimeUnit;
    
    public class AbsTcpServer {
    
        public void start() {
            ServerBootstrap b = new ServerBootstrap();
            EventLoopGroup group = new NioEventLoopGroup();
            EventLoopGroup work = new NioEventLoopGroup();
    
            b.group(group, work)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(getChannel());
    
            try {
                ChannelFuture f = b.bind(8080).sync();
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                group.shutdownGracefully();
                work.shutdownGracefully();
            }
        }
    
        public ChannelInitializer<SocketChannel> getChannel() {
            return new ChannelInitializer<SocketChannel>() {
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline()
                            .addLast(new FirstHandler())
                    ;
    
                }
            };
        }
    
    
    
        public static void main(String[] args) {
            AbsTcpServer absTcpServer = new AbsTcpServer();
            absTcpServer.start();
        }
    
    }

    这样一个基于netty的服务端就完成了。

     

    展开全文
  • Netty服务端和客户端搭建(入门)

    千次阅读 2017-05-03 11:55:40
    本文根据Netty权威指南(第二版)中的案例编写,有些案例中的类在我使用的jar中找不到,所以有所...一、服务端 ①TimeServerpackage netty.server;import io.netty.bootstrap.ServerBootstrap; import io.netty.channe

    本文根据Netty权威指南(第二版)中的案例编写,有些案例中的类在我使用的jar中找不到,所以有所修改。本文使用的版本是netty-all-4.0.46.Final.jar,可以自行去官网下载。

    一、服务端
    ①TimeServer

    package netty.server;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    public class TimeServer {
    
    
        public static void main(String[] args) {
            int port = 8080;
            new TimeServer().bind(port);
        }
    
        public void bind(int port) {
    
            //配置服务端的NIO线程组
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChildChannelHandler());
    
            try {
                //绑定端口,同步等待成功
                ChannelFuture f = b.bind(port).sync();
    
                //等待服务端监听端口关闭
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //优雅退出,释放线程池资源
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }
    

    ②ChildChannelHandler

    package netty.server;
    
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.socket.SocketChannel;
    
    public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline().addLast(new TimeServerHandler());
        }
    }
    

    ③TimeServerHandler

    package netty.server;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import java.util.Date;
    
    public class TimeServerHandler extends ChannelInboundHandlerAdapter {
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            String body = new String(req, "UTF-8");
            System.out.println("The time server receive order : " + body);
            String currentTime = "Query time order".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "Bad Order";
    
            ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
            ctx.write(resp);
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.flush();
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.close();
        }
    }
    

    二、客户端
    ①TimeClient

    package netty.client;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    public class TimeClient {
        public static void main(String[] args) {
            int port = 8080;
            new TimeClient().connect(port, "127.0.0.1");
        }
    
        public void connect(int port, String host) {
            //配置客户端的NIO线程组
            EventLoopGroup group = new NioEventLoopGroup();
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChildChannelHandler());
    
    
            try {
                //发生异步连接操作
                ChannelFuture f = b.connect(host, port).sync();
    
                //等待客户端链路关闭
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //优雅退出,释放NIO线程组
                group.shutdownGracefully();
            }
        }
    }
    

    ②ChildChannelHandler

    package netty.client;
    
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.socket.SocketChannel;
    
    public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new TimeClientHandler());
        }
    }

    ③TimeClientHandler

    package netty.client;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    import java.util.logging.Logger;
    
    public class TimeClientHandler extends ChannelInboundHandlerAdapter {
    
    
        private static final Logger logger = Logger.getLogger(TimeClientHandler.class.getName());
    
        private final ByteBuf firstMessage;
    
        public TimeClientHandler() {
            byte[] req = "Query time order".getBytes();
            firstMessage = Unpooled.buffer(req.length);
            firstMessage.writeBytes(req);
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(firstMessage);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            logger.warning("Unexpected exception from downstream:" + cause.getMessage());
            ctx.close();
        }
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
    
            String body = new String(req, "UTF-8");
            System.out.println("Now is :" + body);
        }
    }
    

    服务端:
    NioEventLoopGroup是个线程组,它包含了一组NIO线程,专门用于网络事件处理,实际上他们就是Reactor线程组。 bossGroup用于服务端接收客户端的连接,workerGroup用于进行SocketChannel的网络读写

    ServerBootstrap对象用于启动NIO服务端的辅助启动类(目的是降低服务端的开发复杂度)

    group()方法将两个NIO线程组当做参数传递到ServerBootstrap中,接着设置创建的Channel为NioServerSocketChannel(对应JDK的NIO类库中的ServerSocketChannel),然后配置NioServerSocketChannel的TCP参数,最后绑定I/O事件的处理类ChildChannelHandler(作用类似于Reactor模式中的Handler类,主要用于处理网络I/O事件,例如记录日志,对消息进行编解码)

    服务端启动辅助类配置完成之后,调用它的bind方法绑定监听端口,随后,调用它的同步阻塞方法sync等待绑定事件操作完成。 完成后Netty会返回一个ChannelFuture,它的作用类似于JDK中java.util.concurrent.Future,主要用于异步操作的通知回调

    f.channel().closeFuture().sync()方法进行阻塞,等待服务端链路关闭之后main函数才退出。
    NIO线程组的shutdownGracefully进行优雅退出,释放跟shutdownGracefully相关的资源

    ChannelHandlerContext的write()只是把待发送的消息放到缓冲数组中,在通过调用flush()方法,将缓冲区中的消息全部写到SocketChannel中

    客户端:首先创建客户端处理I/O读写的NioEventLoopGroup线程组,
    然后创建客户端辅助启动类Bootstrap,随后对其进行配置

    展开全文
  • Netty服务端Channel的创建 1、服务端创建Channel之前的疑问? (1)服务端的Socket在哪里初始化? (2)在哪里accept连接?   2、Netty服务端启动分为四个过程 (1)创建服务端Channel 源码跟踪: bind()...

    Netty服务端Channel的创建

    1、服务端创建Channel之前的疑问?

    (1)服务端的Socket在哪里初始化?

    (2)在哪里accept连接?

     

    2、Netty服务端启动分为四个过程

    (1)创建服务端Channel

    源码跟踪:

    bind()用户代码入口

    进入bind()方法,可以发现initAndRegister()初始化并注册方法

    进入initAndRegister ()方法,可以发现newChannel()创建服务端Channel方法

    源码追踪:

    newSocket()[通过jdk来创建底层jdk channel]

    底层使用的是java包

    NioServerSocketChannelConfig()[tcp参数配置类]

    AbstractNioChannel()-configureBlocking(false)[配置非阻塞模式]

    如果使用Socket IO编程,这句代码必不可少;如果使用Netty编程,这行代码是默认的。

    AbstractChannel[创建id、unsafe、pipeline]

    AbstractChannel表示客户端创建channel

    id表示channel唯一标识

    unsafe表示可以设置tcp参数配置

    pipeline表示可以配置逻辑链

    (2)初始化服务端Channel

    (3)注册selector

    (4)端口绑定

     

    展开全文
  • Netty 是 jboss 提供的一个 Java 开源框架,Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可用性的网络服务器和客户端程序。也就是说 Netty 是一个基于 NIO 的编程框架,使用 Netty ...

    什么是 Netty?

    Netty 是 jboss 提供的一个 Java 开源框架,Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可用性的网络服务器和客户端程序。也就是说 Netty 是一个基于 NIO 的编程框架,使用 Netty 可以快速的开发出一个网络应用。
    由于 Java 自带的 NIO API 使用起来非常复杂,并且还可能出现 Epoll Bug,这使得我们使用原生的 NIO 来进行网络编程存在很大的难度且非常耗时。但是 Netty 良好的设计可以使开发人员快速高效的进行网络应用开发。

    Netty 入门

    搭建项目

    首先需要搭建一个普通的 Maven 项目,JDK 版本为 JDK8。

    引入 Netty 依赖

    由于 Netty5 已经被废弃,目前最新的 Netty 版本是 Netty4。

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

    搭建 Netty 服务端

    public class NettyServer {
    
        public static void main(String[] args) throws Exception {
            NettyServer nettyServer = new NettyServer();
            nettyServer.start(12345);
        }
    
        public void start(int port) throws Exception {
            // 1.定义执行线程组
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                // 2.定义服务类
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                // 3.设置线程池
                serverBootstrap.group(group);
                // 4.设置通道
                serverBootstrap.channel(NioServerSocketChannel.class);
                // 5.绑定端口
                serverBootstrap.localAddress(new InetSocketAddress(port));
                // 6.添加Handler
                serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel channel) {
                        ChannelPipeline pipeline = channel.pipeline();
                        pipeline.addLast("StringDecoder", new StringDecoder());
                        pipeline.addLast("StringEncoder", new StringEncoder());
                        pipeline.addLast("ServerHandler", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) {
                                Channel channel = ctx.channel();
                                System.out.println("server receive UserToken[" + channel.id().asLongText() + "] msg ==> " + msg);
                            }
    
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) {
                                Channel channel = ctx.channel();
                                System.out.println("UserToken[" + channel.id().asLongText() + "] 创建链接");
                                final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("The server created a link!", StandardCharsets.UTF_8));
                                ctx.writeAndFlush(buf.duplicate());
                            }
    
                            @Override
                            public void channelInactive(ChannelHandlerContext ctx) {
                                Channel channel = ctx.channel();
                                System.out.println("UserToken[" + channel.id().asLongText() + "] 断开链接");
                            }
    
                            @Override
                            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                                Channel channel = ctx.channel();
                                System.out.println("UserToken[" + channel.id().asLongText() + "] 发生异常");
                            }
                        });
                    }
                });
                ChannelFuture channelFuture = serverBootstrap.bind().sync();
                channelFuture.channel().closeFuture().sync();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                group.shutdownGracefully().sync();
            }
        }
    }
    

    搭建 Netty 客户端

    public class NettyClient {
    
        public static void main(String[] args) {
            NettyClient nettyClient = new NettyClient();
            nettyClient.start("127.0.0.1", 12345);
        }
    
        public void start(String host, int port) {
            // 1.定义执行线程组
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                // 2.定义客户端类
                Bootstrap clientBootstrap = new Bootstrap();
                // 3.设置线程池
                clientBootstrap.group(group);
                // 4.设置通道
                clientBootstrap.channel(NioSocketChannel.class);
                // 5.添加Handler
                clientBootstrap.handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) {
                        ChannelPipeline pipeline = channel.pipeline();
                        pipeline.addLast("StringDecoder", new StringDecoder());
                        pipeline.addLast("StringEncoder", new StringEncoder());
                        pipeline.addLast("ClientHandler", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) {
                                System.out.println("client receive msg ==> " + msg.toString());
                            }
                        });
                    }
                });
    
                // 6.建立连接
                ChannelFuture channelFuture = clientBootstrap.connect(host, port);
                // 7.测试输入
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                while (true) {
                    System.out.println("Please enter:");
                    String msg = bufferedReader.readLine();
                    channelFuture.channel().writeAndFlush(msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 8.关闭连接
                group.shutdownGracefully();
            }
        }
    }
    

    启动项目

    分别启动 NettyServer 和 NettyClient 的 main 方法,服务器和客户端即可进行简单的通讯。

    展开全文
  • 也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:...
  • Netty服务端与客户端依靠Java序列化传输数据
  • springboot+netty 服务端

    2021-06-07 14:43:18
    搭建服务端 启动类 在springboot中利用netty替换tomcat,关闭tomcat与banner。添加扫描注解 import org.springframework.boot.Banner; import org.springframework.boot.WebApplicationType; import org.spring...
  • Netty服务端启动

    2019-07-28 17:13:07
    将jdk底层的channel注册到事件轮训处理器上,并把netty服务端channel绑定在jdk底层服务端channel上 调jdk底层api,实现对本地端口的监听,绑定成功后,netty会重新向selector注册一个op_accept事件,netty就...
  • 有一个项目用到了netty搭建服务端,主要是接入大量的客户端(目前有500多个客户端的接入),与服务端进行来消息的传送。但是,项目运行到一定时间后(大概10来天左右),链路channel就处于一种inactive的状态,...
  • 服务端Netty搭建

    2016-10-06 23:07:23
    使用Netty框架搭建服务端,包括文件传输和json格式字符串传输两种服务端交互,使用回调接口作为两个服务端的通信方式,包含对基本的文本文件的处理,读写和解析等内容。
  • Netty 服务端创建过程

    2019-10-06 10:51:15
    1.首先通过构造函数创建ServerBootstrap 实例,ServerBootStrap是Netty的启动辅助类。用于设置服务端启动相关的参数 ServerBootstrap bootstrap = new ServerBootstrap(); 2.设置并绑定Reactor线程池,也...
  • 验证Netty服务端线程

    2020-03-09 20:58:21
    本文质量一般,对Netty有一定基础的读者. Netty在处理请求和返回响应的时候,到底使用的是什么线程,是否是同一个线程,如何控制处理的线程? 代码如下 EventLoopGroup bossGroup = new NioEventLoopGroup(1); ...
  • Netty系列之Netty 服务端创建

    千次阅读 2015-04-30 17:08:39
    1. 背景 1.1. 原生NIO类库的复杂性 ...当时两个项目组的设计师都咨询了我的意见,在了解了两个项目团队的NIO编程经验和现状之后,我建议他们都使用Netty构建业务通信框架。令人遗憾的是其中1个项目
  • 主要介绍了使用Netty搭建服务端和客户端过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • demo采用spring boot和maven编写,直接使用maven方式打开项目先运行TimeServer中的main函数再运行TimeClient中的main函数即可在控制台中看到效果
  • 二、Netty服务端hello world 1、导入 pom 2、server 服务端代码 3、测试 4、分析 一、Netty介绍 1、基本介绍 NIO是一个非阻塞的多线程的socket网络通信API 每次使用NIO进行网络通信的时候我们都需要...
  • netty服务端如何能通过websocket同时连接前端js编写的客户端和后端用java写的l两个客户端,已经尝试了写两个自己定义的handler来发送接收数据,但运行时只有一个被调用,有什么解决办法吗?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,246
精华内容 2,098
关键字:

netty服务端搭建