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

netty系列之:使用netty搭建websocket客户端

0
分享至

简介

在网速快速提升的时代,浏览器已经成为我们访问各种服务的入口,很难想象如果离开了浏览器,我们的网络世界应该如何运作。现在恨不得把操作系统都搬上浏览器。但是并不是所有的应用都需要浏览器来执行,比如服务器和服务器之间的通信,就需要使用到自建客户端来和服务器进行交互。

本文将会介绍使用netty客户端连接websocket的原理和具体实现。

浏览器客户端

在介绍netty客户端之前,我们先看一个简单的浏览器客户端连接websocket的例子:

// 创建连接
const socket = new WebSocket('ws://localhost:8000');

// 开启连接
socket.addEventListener('open', function (event) {
socket.send('没错,开启了!');
});

// 监听消息
socket.addEventListener('message', function (event) {
console.log('监听到服务器的消息 ', event.data);
});

这里使用了浏览器最通用的语言javascript,并使用了浏览器提供的websocket API进行操作,非常的简单。

那么用netty客户端实现websocket的连接是否和javascript使用一样呢?我们一起来探索。

netty对websocket客户端的支持

先看看netty对websocket的支持类都有哪些,接着我们看下怎么具体去使用这些工具类。

WebSocketClientHandshaker

和websocket server一样,client中最核心的类也是handshaker,这里叫做WebSocketClientHandshaker。这个类有什么作用呢?一起来看看。

这个类主要实现的就是client和server端之间的握手。

我们看一下它的最长参数的构造类:

protected WebSocketClientHandshaker(URI uri, WebSocketVersion version, String subprotocol,
HttpHeaders customHeaders, int maxFramePayloadLength,
long forceCloseTimeoutMillis, boolean absoluteUpgradeUrl)

参数中有websocket连接的URI,像是:”ws://flydean.com/mypath”。

有请求子协议的类型subprotocol,有自定义的HTTP headers:customHeaders,有最大的frame payload的长度:maxFramePayloadLength,有强制timeout关闭的时间,有使用HTTP协议进行升级的URI地址。

怎么创建handshaker呢?同样的,netty提供了一个WebSocketClientHandshakerFactory方法。

WebSocketClientHandshakerFactory提供了一个newHandshaker方法,可以方便的创建各种不同版本的handshaker:

if (version == V13) {
return new WebSocketClientHandshaker13(
webSocketURL, V13, subprotocol, allowExtensions, customHeaders,
maxFramePayloadLength, performMasking, allowMaskMismatch, forceCloseTimeoutMillis);
}
if (version == V08) {
return new WebSocketClientHandshaker08(
webSocketURL, V08, subprotocol, allowExtensions, customHeaders,
maxFramePayloadLength, performMasking, allowMaskMismatch, forceCloseTimeoutMillis);
}
if (version == V07) {
return new WebSocketClientHandshaker07(
webSocketURL, V07, subprotocol, allowExtensions, customHeaders,
maxFramePayloadLength, performMasking, allowMaskMismatch, forceCloseTimeoutMillis);
}
if (version == V00) {
return new WebSocketClientHandshaker00(
webSocketURL, V00, subprotocol, customHeaders, maxFramePayloadLength, forceCloseTimeoutMillis);
}

可以看到,根据传入协议版本的不同,可以分为WebSocketClientHandshaker13、WebSocketClientHandshaker08、WebSocketClientHandshaker07、WebSocketClientHandshaker00这几种。

WebSocketClientCompressionHandler

通常来说,对于webSocket协议,为了提升传输的性能和速度,降低网络带宽占用量,在使用过程中通常会带上额外的压缩扩展。为了处理这样的压缩扩展,netty同时提供了服务器端和客户端的支持。

对于服务器端来说对应的handler叫做WebSocketServerCompressionHandler,对于客户端来说对应的handler叫做WebSocketClientCompressionHandler。

通过将这两个handler加入对应pipline中,可以实现对websocket中压缩协议扩展的支持。

对于协议的扩展有两个级别分别是permessage-deflate和perframe-deflate,分别对应PerMessageDeflateClientExtensionHandshaker和DeflateFrameClientExtensionHandshaker。

至于具体怎么压缩的,这里就不详细进行讲解了, 感兴趣的小伙伴可以自行了解。

netty客户端的处理流程

前面讲解了netty对websocket客户端的支持之后,本节将会讲解netty到底是如何使用这些工具进行消息处理的。

首先是按照正常的逻辑创建客户端的Bootstrap,并添加handler。这里的handler就是专门为websocket定制的client端handler。

除了上面提到的WebSocketClientCompressionHandler,就是自定义的handler了。

在自定义handler中,我们需要处理两件事情,一件事情就是在channel ready的时候创建handshaker。另外一件事情就是具体websocket消息的处理了。

创建handshaker

首先使用WebSocketClientHandshakerFactory创建handler:

TestSocketClientHandler handler =
new TestSocketClientHandler(
WebSocketClientHandshakerFactory.newHandshaker(
uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()));

然后在channel active的时候使用handshaker进行握手连接:

public void channelActive(ChannelHandlerContext ctx) {
handshaker.handshake(ctx.channel());
}

然后在进行消息接收处理的时候还需要判断handshaker的状态是否完成,如果未完成则调用handshaker.finishHandshake方法进行手动完成:

if (!handshaker.isHandshakeComplete()) {
try {
handshaker.finishHandshake(ch, (FullHttpResponse) msg);
log.info("websocket Handshake 完成!");
handshakeFuture.setSuccess();
} catch (WebSocketHandshakeException e) {
log.info("websocket连接失败!");
handshakeFuture.setFailure(e);
}
return;
}

当handshake完成之后,就可以进行正常的websocket消息读写操作了。

websocket消息的处理

websocket的消息处理比较简单,将接收到的消息转换成为WebSocketFrame进行处理即可。

WebSocketFrame frame = (WebSocketFrame) msg;
if (frame instanceof TextWebSocketFrame) {
TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
log.info("接收到TXT消息: " + textFrame.text());
} else if (frame instanceof PongWebSocketFrame) {
log.info("接收到pong消息");
} else if (frame instanceof CloseWebSocketFrame) {
log.info("接收到closing消息");
ch.close();
}
总结

本文讲解了netty提供的websocket客户端的支持和具体的对接流程,大家可以再次基础上进行扩展,以实现自己的业务逻辑。

本文的例子可以参考:learn-netty4

本文已收录于 http://www.flydean.com/25-netty-websocket-client/

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

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.

相关推荐
热点推荐
美国的渗透开始奏效,扶持的内鬼纷纷在华露头,专家:全部铲除!

美国的渗透开始奏效,扶持的内鬼纷纷在华露头,专家:全部铲除!

小lu侃侃而谈
2024-06-02 21:40:53
沁县政协主席身亡后续:动机曝光,评论区沦陷,凶手身份不简单

沁县政协主席身亡后续:动机曝光,评论区沦陷,凶手身份不简单

蜗牛壳里
2024-06-08 00:06:25
一个幼儿园的孩子根本不认识毛主席,却说:这个老爷爷好慈祥

一个幼儿园的孩子根本不认识毛主席,却说:这个老爷爷好慈祥

大江
2024-06-07 15:51:02
吴冠希来香港探望爱妻,陪张常宁购物!满脸宠爱,全程为老婆提包

吴冠希来香港探望爱妻,陪张常宁购物!满脸宠爱,全程为老婆提包

金毛爱女排
2024-06-07 09:26:29
泽连斯基突然来到现场,当着40多国代表,对中国“出言不逊”

泽连斯基突然来到现场,当着40多国代表,对中国“出言不逊”

科罗廖夫
2024-06-07 08:05:03
英媒:中国国旗能在月球上存在一万年! 阿波罗登月的美国旗还在吗

英媒:中国国旗能在月球上存在一万年! 阿波罗登月的美国旗还在吗

奇趣科学探秘
2024-06-07 17:44:57
退休人员基本养老金翻番!社保待遇稳步提升

退休人员基本养老金翻番!社保待遇稳步提升

新华社
2024-06-08 19:49:03
矮小亚裔被8名白人围殴,反抗干掉6人,美警:枪枪爆头,像猎野猪

矮小亚裔被8名白人围殴,反抗干掉6人,美警:枪枪爆头,像猎野猪

古今档案
2023-10-31 18:58:25
不到17岁!欧洲杯最小球员:他出生时,C罗已是世界第2巨星

不到17岁!欧洲杯最小球员:他出生时,C罗已是世界第2巨星

叶青足球世界
2024-06-08 10:04:45
6月7日,张学友冲上热搜!自曝感染了罕见病毒RSV十分歉疚

6月7日,张学友冲上热搜!自曝感染了罕见病毒RSV十分歉疚

山野下
2024-06-07 21:07:13
这女的又火了一遍

这女的又火了一遍

gogoDaily
2024-06-07 10:25:02
55年,许世友接电话口出狂言:我是大将军!对面答:我是小兵恩来

55年,许世友接电话口出狂言:我是大将军!对面答:我是小兵恩来

历史龙元阁
2024-06-07 20:07:54
汪涵妻子杨乐乐推崇地中海饮食被嘲:就这智商难怪被骗钱!

汪涵妻子杨乐乐推崇地中海饮食被嘲:就这智商难怪被骗钱!

毒舌嬷嬷
2024-06-07 07:42:28
严师出高徒!孙继海纠正小球员动作,细化教导防守步伐的细节

严师出高徒!孙继海纠正小球员动作,细化教导防守步伐的细节

直播吧
2024-06-08 14:30:21
正在公示!首批15个城市,拟获中央财政支持

正在公示!首批15个城市,拟获中央财政支持

鲁中晨报
2024-06-02 11:55:03
全国多家档口跑路!诈骗金额超千万,套路曝光,多位受害人发声!

全国多家档口跑路!诈骗金额超千万,套路曝光,多位受害人发声!

古希腊掌管松饼的神
2024-06-07 17:15:34
大师!克罗斯对阵希腊传球成功率97%,送出6脚准确长传

大师!克罗斯对阵希腊传球成功率97%,送出6脚准确长传

直播吧
2024-06-08 14:49:03
中国主动出击,判了菲律宾“死刑”,南海亮剑时刻已到

中国主动出击,判了菲律宾“死刑”,南海亮剑时刻已到

劲松talk
2024-06-08 12:00:58
如果中国队未进入18强将回归平淡!预测一下将会发生的大事件

如果中国队未进入18强将回归平淡!预测一下将会发生的大事件

看懂帝国
2024-06-08 18:24:38
当硬汉爱上“美甲”,无需再去证明“男子气概”|深度报道

当硬汉爱上“美甲”,无需再去证明“男子气概”|深度报道

北青深一度
2024-06-08 12:47:04
2024-06-08 20:08:49
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

今年数学到底有多难?大模型:我也不太会

头条要闻

贪官42岁升副科级自认为"大器晚成" 对送钱的人说感谢

头条要闻

贪官42岁升副科级自认为"大器晚成" 对送钱的人说感谢

体育要闻

她拯救了WNBA,却为何被疯狂针对?

娱乐要闻

汤唯抵达巴黎将担任奥运火炬手

财经要闻

重磅详解:为什么美国经济还没有衰退?

汽车要闻

上汽大通大家9售26.99万起 综合续航1300km+

态度原创

房产
时尚
家居
手机
亲子

房产要闻

顶流地段+顶级户型!香港半山豪宅,已成为高净值人群的资产压舱石!

有魅力的女人都很擅长穿搭!学会这几种穿法,优雅高级又养眼

家居要闻

柔和婉转 让阳光洒满空间

手机要闻

vivo S19系列正式发售,蓝厂对首销日的描述才是重点

亲子要闻

孩子去太姥家,老人家送给孩子一个金手镯,宝宝看到镯子的反应逗笑众人

无障碍浏览 进入关怀版