利用netty简单实现聊天室
时间:2018-12-15
本文章向大家介绍利用netty简单实现聊天室,主要包括利用netty简单实现聊天室相关应用实例、知识点总结和注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1.导入依赖包
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha1</version> </dependency>
2.netty服务端代码
public class NettyServer { public static void main(String[] args) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap bootStrap = new ServerBootstrap(); ChannelFuture cf; bootStrap.group(bossGroup,workGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast("decoder", new StringDecoder());//需要编解码,否则无法解析 p.addLast("encoder", new StringEncoder()); p.addLast(new NettyServerHandler()); } }); try { cf = bootStrap.bind(8099).sync();//监听8099端口 System.out.println("8099:binded..."); cf.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } }
3.netty客户端代码
public class NettyClient { public static void main(String[] args) throws Exception { EventLoopGroup group =new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>(){ @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast("decoder", new StringDecoder()); p.addLast("encoder", new StringEncoder()); p.addLast(new ClientHandler()); p.addLast(new ClientHandlerBak()); } }); ChannelFuture future = b.connect("127.0.0.1", 8099).sync(); future.channel().writeAndFlush("这里是客户端,请求连接服务端!"); future.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } }
4.服务端处理类
public class NettyServerHandler extends ChannelHandlerAdapter { //有客户端连接时触发 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("one client connect..."); } //断开连接时触发 @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("one client disconnect..."); } //接收客户端发送的消息 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("客户端:"+msg.toString()); InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); String result ="result"; try{ result = br.readLine(); } catch(IOException e){ e.printStackTrace(); } ctx.write(result);//给客户端回复 ctx.flush(); } }
5.客户端处理类
public class ClientHandler extends ChannelHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("Client01Handler Active"); /*若把这一句注释掉将无法将event传递给下一个ClientHandler,例如例子中p.addLast(new Client01Handler())后面紧跟着p.addLast(new Client02Handler()) 后面的Client02Handler里的方法就不会被触发。 */ ctx.fireChannelActive(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("服务端: "+msg); InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); String result ="result"; try{ result = br.readLine(); } catch(IOException e){ e.printStackTrace(); } ctx.write(result);//给服务端回复 ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
6.最后,看看效果,先启动服务端,再启动客户端
- Apache Spark作为编译器:深入介绍新的Tungsten执行引擎
- DC/OS 的安装与部署
- Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑
- 4个简单的数据管理技巧
- MongoDB的设计模式策略
- 如何用容器实现生产级Redis sharding集群一键交付
- Hadoop旧mapreduce的map任务切分原理
- 解读Neo4j全新的Python驱动程序
- MySQL 5.7 X Plugin:流水线技术vs.并行查询技术
- 在下函数式编程,有何贵干?
- 基于Keras/Python的深度学习模型Dropout正则项
- 揭秘深度强化学习
- Swoole-2.0.1-Alpha 已发布,提供PHP原生协程支持
- Google核心技术之——PageRank算法scala实现
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 完美解决 python ImportError: Failed to import any qt binding
- 爬取娱乐圈排行榜数据
- 如何解决Linux系统下pyaudio安装缺少文件问题error: portaudio.h: 没有那个文件或目录
- pytest 测试框架学习(10):pytest.param
- pytest 测试框架学习(11):pytest.raises
- Hibernate第二天:Hibernate的一级缓存、其他的API
- pytest 测试框架学习(12):pytest.deprecated_call
- Pinstaller(Python打包为exe文件
- pytest 测试框架学习(14):pytest.warns
- ImportError: /lib64/libm.so.6: version `CXXAB_1.3.8.' not found (required by /usr/local/python37/lib
- pytest 测试框架学习(15):pytest.freeze_includes
- Linux: scp文件,目录上传下载标准版
- Hibernate第三天:Hibernate的一对多配置、Hibernate的多对多的配置
- Git: 掉坑记 -- git reset 杀手
- ModuleNotFoundError: No module named 'phkit.pinyin'