网易首页 > 网易号 > 正文 申请入驻

netty系列之:文本聊天室

0
分享至

简介

经过之前的系列文章,我们已经知道了netty的运行原理,还介绍了基本的netty服务搭建流程和消息处理器的写法。今天本文会给大家介绍一个更加复杂的例子,文本聊天室。

聊天室的工作流程

今天要介绍的是文本聊天室,对于文本聊天室来说,首先需要建立一个服务器,用于处理各个客户端的连接,对于客户端来说,需要建立和服务器的连接,然后向服务器输入聊天信息。服务器收到聊天信息之后,会对消息进行响应,并将消息返回至客户端,这样一个聊天室的流程就完成了。

文本处理器

之前的文章中,我们有提到过,netty的传输只支持ByteBuf类型,对于聊天室直接输入的字符串是不支持的,需要对字符串进行encode和decode转换。

之前我们介绍的encode和decode的类叫做ObjectDecoder和ObjectEncoder。今天我们再介绍两个专门处理字符串的StringDecoder和StringEncoder。

StringEncoder要比ObjectEncoder简单很多,因为对于对象来说,我们还需要在Byte数组的头部设置Byte数组的大小,从而保证对象所有数据读取正确。对于String来说,就比较简单了,只需要保证一次读入的数据都是字符串即可。

StringEncoder继承自MessageToMessageEncoder,其核心的encode代码如下:

protected void encode(ChannelHandlerContext ctx, CharSequence msg, List out) throws Exception {
if (msg.length() == 0) {
return;

out.add(ByteBufUtil.encodeString(ctx.alloc(), CharBuffer.wrap(msg), charset));
}

从上面的代码可以看出,核心实际上是调用了ByteBufUtil.encodeString方法,将String转换成了ByteBuf。

对于字符串编码来说,还需要界定一个编码的范围,比如我们需要知道需要一次编码多少字符串,一般来说我们通过回车符来界定一次字符串输入的结束。

netty也提供了这样的非常便利的类叫做DelimiterBasedFrameDecoder,通过传入不同的Delimiter,我们可以将输入拆分成不同的Frame,从而对一行字符串进行处理。

new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()))

我再看一下StringDecoder的核心代码,StringDecoder继承自MessageToMessageDecoder:

protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception {
out.add(msg.toString(charset));

通过调用ByteBuf的toString方法,将BuyteBuf转换成为字符串,并且输出到channel中。

初始化ChannelHandler

在initChannel的时候,我们需要向ChannelPipeline中添加有效的Handler。对于本例来说,需要添加StringDecoder、StringEncoder、DelimiterBasedFrameDecoder和真正处理消息的自定义handler。

我们将初始化Pipeline的操作都放在一个新的ChatServerInitializer类中,这个类继承自ChannelInitializer,其核心的initChannel方法如下:

public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 添加行分割器
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
// 添加String Decoder和String Encoder,用来进行字符串的转换
pipeline.addLast(DECODER);
pipeline.addLast(ENCODER);
// 最后添加真正的处理器
pipeline.addLast(SERVER_HANDLER);

ChatServerInitializer在Bootstrap中的childHandler中进行添加:

childHandler(new ChatServerInitializer())
真正的消息处理逻辑

有了上面的逻辑之后,我们最后只需要专注于真正的消息处理逻辑即可。

这里我们的逻辑是当客户端输入“再见”的时候,就关闭channel,否则就将消息回写给客户端。

其核心逻辑如下:

public void channelRead0(ChannelHandlerContext ctx, String request) throws Exception {
// 如果读取到"再见"就关闭channel
String response;
// 判断是否关闭
boolean close = false;
if (request.isEmpty()) {
response = "你说啥?\r\n";
} else if ("再见".equalsIgnoreCase(request)) {
response = "再见,我的朋友!\r\n";
close = true;
} else {
response = "你是不是说: '" + request + "'?\r\n";

// 写入消息
ChannelFuture future = ctx.write(response);
// 添加CLOSE listener,用来关闭channel
if (close) {
future.addListener(ChannelFutureListener.CLOSE);
}
}

通过判断客户端的出入,来设置是否关闭按钮,这里的关闭channel是通过向ChannelFuture中添加ChannelFutureListener.CLOSE来实现的。

ChannelFutureListener.CLOSE是一个ChannelFutureListener,它会在channel执行完毕之后关闭channel,事实上这是一个非常优雅的关闭方式。

ChannelFutureListener CLOSE = new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
future.channel().close();

对于客户端来说,其核心就是从命令行读取输入,这里使用InputStreamReader接收命令行输入,并使用BufferedReader对其缓存。

然后将命令行输入通过调用 ch.writeAndFlush写入到channel中,最后监听命令行输入,如果监听到“再见“,则等待server端关闭channel,其核心代码如下。

// 从命令行输入
ChannelFuture lastWriteFuture = null;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
for (;;) {
String line = in.readLine();
if (line == null) {
break;
// 将从命令行输入的一行字符写到channel中
lastWriteFuture = ch.writeAndFlush(line + "\r\n");
// 如果输入'再见',则等待server端关闭channel
if ("再见".equalsIgnoreCase(line)) {
ch.closeFuture().sync();
break;

// 等待所有的消息都写入channel中
if (lastWriteFuture != null) {
lastWriteFuture.sync();
}

总结

经过上面的介绍,一个简单的聊天室就建成了。后续我们会继续探索更加复杂的应用,希望大家能够喜欢。

本文已收录于 http://www.flydean.com/10-netty-chat/

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
台湾问题即将突破临界点,两大迹象表明,大陆或要准备出手了?

台湾问题即将突破临界点,两大迹象表明,大陆或要准备出手了?

铭记历史呀
2026-06-29 16:49:31
心理学上有个词叫“空椅子技巧”:讨厌一个人时,其实不必闹翻脸,最高级的处理方式就是用“空椅子技巧”

心理学上有个词叫“空椅子技巧”:讨厌一个人时,其实不必闹翻脸,最高级的处理方式就是用“空椅子技巧”

心理观察局
2026-06-16 07:47:21
如果没有安切洛蒂巴西恐被爆冷,针对性战术+神级换人拿捏住日本

如果没有安切洛蒂巴西恐被爆冷,针对性战术+神级换人拿捏住日本

杨华评论
2026-06-30 04:06:37
交管12123正式提醒!车位被堵车主不留电话,一招轻松叫人挪车

交管12123正式提醒!车位被堵车主不留电话,一招轻松叫人挪车

娱乐洞察点点
2026-06-29 12:37:30
李小璐含泪复盘过往:年轻时太恋爱脑,如今无戏可拍满心自卑

李小璐含泪复盘过往:年轻时太恋爱脑,如今无戏可拍满心自卑

观鱼听雨
2026-06-29 23:54:36
俄军三线都要收尾了!

俄军三线都要收尾了!

星火聊天下
2026-06-30 07:16:16
一人如实申报境外所得150万个税,被税务通报表扬

一人如实申报境外所得150万个税,被税务通报表扬

第一财经资讯
2026-06-29 14:08:10
WTT美国大满贯:女单大爆冷!世界第9被淘汰,国乒3:1,朱雨玲3:1

WTT美国大满贯:女单大爆冷!世界第9被淘汰,国乒3:1,朱雨玲3:1

国乒二三事
2026-06-30 05:26:40
恭喜文班亚马!恭喜马刺!快船拒绝1.26亿续约,小卡或重回老东家

恭喜文班亚马!恭喜马刺!快船拒绝1.26亿续约,小卡或重回老东家

鸣哥说体育
2026-06-29 19:31:40
FIFA被呼吁调查世界杯阿尔及利亚3-3奥地利比赛,双方替补席爆发诡异冲突引发球迷“默契球”猜测,两队被质疑做局淘汰伊朗

FIFA被呼吁调查世界杯阿尔及利亚3-3奥地利比赛,双方替补席爆发诡异冲突引发球迷“默契球”猜测,两队被质疑做局淘汰伊朗

鲁中晨报
2026-06-29 19:58:03
超级富二代的自我毁灭:玩游戏、追网红,两年败光3个亿

超级富二代的自我毁灭:玩游戏、追网红,两年败光3个亿

小怪吃美食
2026-06-27 14:57:44
怒发冲冠!200名韩国球迷凌晨4点接机主教练,敲鼓怒吼:洪明甫滚蛋!

怒发冲冠!200名韩国球迷凌晨4点接机主教练,敲鼓怒吼:洪明甫滚蛋!

818体育
2026-06-30 11:06:53
官方出手!韩红风波再升级,贪污上亿传闻水落石出 恐走闫学晶老路

官方出手!韩红风波再升级,贪污上亿传闻水落石出 恐走闫学晶老路

陈意小可爱
2026-06-30 06:53:39
马耳他著名拱门坍塌,致一名26岁中国男子身亡,一名27岁中国女子受重伤,事发前一美国游客从拱门跳下,当地法官已对此事展开调查

马耳他著名拱门坍塌,致一名26岁中国男子身亡,一名27岁中国女子受重伤,事发前一美国游客从拱门跳下,当地法官已对此事展开调查

鲁中晨报
2026-06-30 07:34:45
33岁老板娘出轨18岁暑假工,高调挑衅最终落得家店两空

33岁老板娘出轨18岁暑假工,高调挑衅最终落得家店两空

周哥一影视
2026-06-29 18:23:39
斯卡洛尼紧急调整计划:阿根廷全队放假,应对美国极端高温

斯卡洛尼紧急调整计划:阿根廷全队放假,应对美国极端高温

宝哥精彩赛事
2026-06-30 01:31:31
董文华:我这辈子最正确的决定,就是嫁给了一个平凡普通的丈夫

董文华:我这辈子最正确的决定,就是嫁给了一个平凡普通的丈夫

飘飘然的娱乐汇
2026-06-27 20:35:10
出差归来女儿变光头,我带剃刀到学校,当着全校给女老师剃光头

出差归来女儿变光头,我带剃刀到学校,当着全校给女老师剃光头

墨染尘香
2026-06-29 09:06:44
尹乃菁离职后撕破脸 狠批郑丽文“不授权” 拒绝承认还是姐妹!

尹乃菁离职后撕破脸 狠批郑丽文“不授权” 拒绝承认还是姐妹!

娱乐的宅急便
2026-06-30 06:18:20
悲惨!7亿豪阵创2大耻辱纪录,暴露3大弊端,纳帅嘴硬,直喷裁判

悲惨!7亿豪阵创2大耻辱纪录,暴露3大弊端,纳帅嘴硬,直喷裁判

萌兰聊个球
2026-06-30 09:47:22
2026-06-30 11:47:00
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

DeepSeek V4正式版要来 高峰期API价格翻倍

头条要闻

牛弹琴:韩国对男足耻辱出局激烈反应 全世界震惊不已

头条要闻

牛弹琴:韩国对男足耻辱出局激烈反应 全世界震惊不已

体育要闻

日本众将掩面痛哭 连续3届先破门却被逆转

娱乐要闻

韩红称要退出公益,多位名人挽留

财经要闻

韩国万亿"芯"基建:存储能否成AI时代油田

汽车要闻

谁懂啊家人们!爹味和班味一点都没,这台底盘最硬国产大猎装太上头!

态度原创

健康
艺术
手机
教育
游戏

狂吃“糯叽叽”小心肠梗阻!

艺术要闻

40年从未停手,她是北京最野才女

手机要闻

快升级!苹果发布iOS 26.5.2:修复大量漏洞

教育要闻

5秒钟搞定一道中考几何题

大表哥2开发者谈GTA6 60帧:早有预言 稳60帧太夸张

无障碍浏览 进入关怀版