原作者江成军,原题“还在被Java NIO虐?该试试Netty了”,即时通讯网收录时有修订和改动。
import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; /** * @Date: 2020/6/1 11:12 * @Description: 通用handler,处理I/O事件 */ @ChannelHandler.Sharable public class HandlerClientHello extends SimpleChannelInboundHandler<ByteBuf> { @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { /** * @Description 处理接收到的消息 **/ System.out.println("接收到的消息:"+byteBuf.toString(CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { /** * @Description 处理I/O事件的异常 **/ cause.printStackTrace(); ctx.close(); } }
import com.sun.org.apache.bcel.internal.generic.ATHROW; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.Unpooled; 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; import io.netty.util.CharsetUtil; import java.net.InetSocketAddress; /** * @Date: 2020/6/1 11:24 * @Description: 客户端启动类 */ public class AppClientHello { private final String host; private final int port; public AppClientHello(String host, int port) { this.host = host; this.port = port; } public void run() throws Exception { /** * @Description 配置相应的参数,提供连接到远端的方法 **/ EventLoopGroup group = new NioEventLoopGroup();//I/O线程池 try { Bootstrap bs = new Bootstrap();//客户端辅助启动类 bs.group(group) .channel(NioSocketChannel.class)//实例化一个Channel .remoteAddress(new InetSocketAddress(host,port)) .handler(new ChannelInitializer<SocketChannel>()//进行通道初始化配置 { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new HandlerClientHello());//添加我们自定义的Handler } }); //连接到远程节点;等待连接完成 ChannelFuture future=bs.connect().sync(); //发送消息到服务器端,编码格式是utf-8 future.channel().writeAndFlush(Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8)); //阻塞操作,closeFuture()开启了一个channel的监听器(这期间channel在进行各项工作),直到链路断开 future.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws Exception { new AppClientHello("127.0.0.1",18080).run(); } }
import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.CharsetUtil; /** * @Date: 2020/6/1 11:47 * @Description: 服务器端I/O处理类 */ @ChannelHandler.Sharable public class HandlerServerHello extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //处理收到的数据,并反馈消息到到客户端 ByteBuf in = (ByteBuf) msg; System.out.println("收到客户端发过来的消息: " + in.toString(CharsetUtil.UTF_8)); //写入并发送信息到远端(客户端) ctx.writeAndFlush(Unpooled.copiedBuffer("你好,我是服务端,我已经收到你发送的消息", CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { //出现异常的时候执行的动作(打印并关闭通道) cause.printStackTrace(); ctx.close(); } }
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.net.InetSocketAddress; /** * @Date: 2020/6/1 11:51 * @Description: 服务器端启动类 */ public class AppServerHello { private int port; public AppServerHello(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup group = new NioEventLoopGroup();//Netty的Reactor线程池,初始化了一个NioEventLoop数组,用来处理I/O操作,如接受新的连接和读/写数据 try { ServerBootstrap b = new ServerBootstrap();//用于启动NIO服务 b.group(group) .channel(NioServerSocketChannel.class) //通过工厂方法设计模式实例化一个channel .localAddress(new InetSocketAddress(port))//设置监听端口 .childHandler(new ChannelInitializer<SocketChannel>() { //ChannelInitializer是一个特殊的处理类,他的目的是帮助使用者配置一个新的Channel,用于把许多自定义的处理类增加到pipline上来 @Override public void initChannel(SocketChannel ch) throws Exception {//ChannelInitializer 是一个特殊的处理类,他的目的是帮助使用者配置一个新的 Channel。 ch.pipeline().addLast(new HandlerServerHello());//配置childHandler来通知一个关于消息处理的InfoServerHandler实例 } }); //绑定服务器,该实例将提供有关IO操作的结果或状态的信息 ChannelFuture channelFuture= b.bind().sync(); System.out.println("在" + channelFuture.channel().localAddress()+"上开启监听"); //阻塞操作,closeFuture()开启了一个channel的监听器(这期间channel在进行各项工作),直到链路断开 channelFuture.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync();//关闭EventLoopGroup并释放所有资源,包括所有创建的线程 } } public static void main(String[] args) throws Exception { new AppServerHello(18080).run(); } }
来源:即时通讯网 - 即时通讯开发者社区!
轻量级开源移动端即时通讯框架。
快速入门 / 性能 / 指南 / 提问
轻量级Web端即时通讯框架。
详细介绍 / 精编源码 / 手册教程
移动端实时音视频框架。
详细介绍 / 性能测试 / 安装体验
基于MobileIMSDK的移动IM系统。
详细介绍 / 产品截图 / 安装体验
一套产品级Web端IM系统。
详细介绍 / 产品截图 / 演示视频
精华主题数超过100个。
连续任职达2年以上的合格正式版主
为论区做出突出贡献的开发者、版主等。
Copyright © 2014-2024 即时通讯网 - 即时通讯开发者社区 / 版本 V4.4
苏州网际时代信息科技有限公司 (苏ICP备16005070号-1)
Processed in 0.125000 second(s), 48 queries , Gzip On.