netty实现websocket发送文本和二进制数据
原文:https://huan1993.iteye.com/blog/2433552
最近在学习netty相关的知识,看到netty可以实现 websoket,因此记录一下在netty中实现websocket的步骤,主要实现传递文本消息和传递二进制消息,传递二进制消息由于需要传递额外信息,因此使用自定义消息协议。
需求:
1、使用 netty 实现 websocket 服务器
2、实现 文本信息 的传递
3、实现 二进制 信息的传递,如果是图片则传递到后台后在前台直接显示,非图片提示。(此处的图片和非图片是前端传递到后台的二进制数据然后后端在原封不动的直接返回到前台)
4、只需要考虑 websocket 协议,不用处理http请求
实现细节:
1、netty中对websocket增强的处理器
WebSocketServerProtocolHandler
>> 此处理器可以处理了 webSocket 协议的握手请求处理,以及 Close、Ping、Pong控制帧的处理。对于文本和二进制的数据帧需要我们自己处理。
>> 如果我们需要拦截 webSocket 协议握手完成后的处理,可以实现ChannelInboundHandler#userEventTriggered方法,并判断是否是 HandshakeComplete 事件。
>> 参数:websocketPath 表示 webSocket 的路径
>> 参数:maxFrameSize 表示最大的帧,如果上传大文件时需要将此值调大
2、文本消息的处理
客户端: 直接发送一个字符串即可
服务端: 服务端给客户端响应文本数据,需要返回 TextWebSocketFrame 对象,否则客户端接收不到。
3、二进制消息的处理
客户端:向后台传递一个 blob 对象即可,如果我们需要传递额外的信息,那么可以在 blob 对象中进行添加,此例中自定义前4个字节表示数据的类型。
服务端:处理 BinaryWebSocketFrame 帧,并获取前4个字节,判断是否是图片,然后返回 BinaryWebSocketFrame对象给前台。
4、针对二进制消息的自定义协议如下:(此处实现比较简单)
前四个字节表示文件类型,后面的字节表示具体的数据。
在java中一个int是4个字节,在js中使用Int32表示
此协议主要是判断前端是否传递的是 图片,如果是图片就直接传递到后台,然后后台在返回二进制数据到前台直接显示这个图片。非图片不用处理。
5、js中处理二进制数据
见 webSocket.html 文件中的处理。
实现步骤:
1、主要的依赖
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
- <version>4.1.31.Final</version>
- </dependency>
2、webSocket服务端编写
- @Slf4j
- public class WebSocketServer {
- public static void main(String[] args) throws InterruptedException {
- EventLoopGroup bossGroup = new NioEventLoopGroup();
- EventLoopGroup workGroup = new NioEventLoopGroup();
- try {
- ServerBootstrap bootstrap = new ServerBootstrap();
- bootstrap.group(bossGroup, workGroup)
- .option(ChannelOption.SO_BACKLOG, 128)
- .childOption(ChannelOption.TCP_NODELAY, true)
- .childOption(ChannelOption.SO_KEEPALIVE, true)
- .handler(new LoggingHandler(LogLevel.TRACE))
- .channel(NioServerSocketChannel.class)
- .childHandler(new ChannelInitializer<SocketChannel>() {
- @Override
- protected void initChannel(SocketChannel ch) throws Exception {
- ch.pipeline()
- .addLast(new LoggingHandler(LogLevel.TRACE))
- // HttpRequestDecoder和HttpResponseEncoder的一个组合,针对http协议进行编解码
- .addLast(new HttpServerCodec())
- // 分块向客户端写数据,防止发送大文件时导致内存溢出, channel.write(new ChunkedFile(new File("bigFile.mkv")))
- .addLast(new ChunkedWriteHandler())
- // 将HttpMessage和HttpContents聚合到一个完成的 FullHttpRequest或FullHttpResponse中,具体是FullHttpRequest对象还是FullHttpResponse对象取决于是请求还是响应
- // 需要放到HttpServerCodec这个处理器后面
- .addLast(new HttpObjectAggregator(10240))
- // webSocket 数据压缩扩展,当添加这个的时候WebSocketServerProtocolHandler的第三个参数需要设置成true
- .addLast(new WebSocketServerCompressionHandler())
- // 服务器端向外暴露的 web socket 端点,当客户端传递比较大的对象时,maxFrameSize参数的值需要调大
- .addLast(new WebSocketServerProtocolHandler("/chat", null, true, 10485760))
- // 自定义处理器 - 处理 web socket 文本消息
- .addLast(new TextWebSocketHandler())
- // 自定义处理器 - 处理 web socket 二进制消息
- .addLast(new BinaryWebSocketFrameHandler());
- }
- });
- ChannelFuture channelFuture = bootstrap.bind(9898).sync();
- log.info("webSocket server listen on port : [{}]", 9898);
- channelFuture.channel().closeFuture().sync();
- } finally {
- bossGroup.shutdownGracefully();
- workGroup.shutdownGracefully();
- }
- }
- }
注意:
1、看一下上方依次引入了哪些处理器
2、对于 webSocket 的握手、Close、Ping、Pong等的处理,由 WebSocketServerProtocolHandler 已经处理了,我们自己只需要处理 Text和Binary等数据帧的处理。
3、对于传递比较大的文件,需要修改 maxFrameSize 参数。
3、自定义处理器握手后和文本消息
netty实现websocket发送文本和二进制数据的更多相关文章
- 【python】3.x,string与bytes的区别(文本,二进制数据)
Python 3对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示, 二进制数据则由bytes类型表示. 不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也 ...
- 前端如何接收 websocket 发送过来的实时数据
WebSocket protocol 是HTML5一种新的协议,它实现了浏览器与服务器全双工通信(full-duple).刚开始的握手需要借助HTTP请求完成,在 WebSocket API,浏览器和 ...
- 详细解读XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
本文主要参考:MDN 分析并操作 responseXML属性 如果你使用 XMLHttpRequest 来获得一个远程的 XML 文档的内容,responseXML 属性将会是一个由 XML 文档解析 ...
- IO流-文本IO\读写二进制数据
文本IO 一.简述 OutputStreamWriter类使用选定的编码方式吧Unicode字符流转换为字节流,InputStreamReader类将包含字节的输入流转为可以产生Unicode字符的读 ...
- Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)
目录 SignalR系列目录(注意,是ASP.NET的目录.不是Core的) 前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于Signal ...
- 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据
[源码下载] 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 读写文本数 ...
- Java模拟POST请求发送二进制数据
在进行程序之间数据通信时我们有时候就需要自定义二进制格式,然后通过HTTP进行二进制数据交互.交互的示例代码如下: public static void main(String[] args) { S ...
- Hibernate 中 联合主键映射 组合关系映射 大对象映射(或者说文本大对象,二进制数据大对象)
Clob:文本大对象,最长4G Blob:二进制数据大对象,最长4G util: public class HibUtil { private static SessionFactory sessio ...
- [ActionScript 3.0] AS利用ByteArray向PHP发送二进制数据生成图片
flash as3向php发送二进制数据,通过php保存成图片. AS端: package { import com.JPEGEncoder.JPGEncoder; import flash.disp ...
随机推荐
- [LeetCode] 800. Similar RGB Color 相似的红绿蓝颜色
In the following, every capital letter represents some hexadecimal digit from 0 to f. The red-green- ...
- [LeetCode] 802. Find Eventual Safe States 找到最终的安全状态
In a directed graph, we start at some node and every turn, walk along a directed edge of the graph. ...
- LeetCode:四数之和【18】
LeetCode:四数之和[18] 题目描述 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c ...
- harbor镜像仓库-https访问配置
1. 证书的生成 在测试或开发环境中,您可以选择使用自签名证书,而不是来自受信任的第三方CA的证书.以下内容将向您展示如何创建自己的CA,并使用您的CA签署服务器证书和客户端证书. 1.1 生成c ...
- Robot Framework 读取控制面板安装的程序,判断某个程序是否已经安装
wmic /output:D:\\DOAutomationTest\\automation_do_robotframework\\installList.txt product get name
- MapReduce面试题
什么是mapreduce Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于hadoop的数据分析应用”的核心框架.容错高,扩展好,适合pB数据处理 MapReduce 执行过程分析 ...
- Spark源码(1) Spark配置
写熟悉的第一句代码 val conf = new SparkConf().setAppName("WordCount")点击SparkConf() ,发现 private val ...
- 一个php将数据库的数据导出到excle表格中的小dome
首先我们需要下载个PHPExcel,PHPExcel下载地址链接:https://pan.baidu.com/s/1nxpAc45 密码:qgct 下面来写个dome: <?php //把数据写 ...
- Delphi Sysem.JSON 链式写法
链式写法有很多优点:连贯.语意集中.简洁.一气呵成.可读性强.比如要把 3.1415926 中的 59 提取为一个整数:Pi.ToString().Substring(5,2).ToInteger() ...
- UiPath-level3-test1 and test2 答案
需要的请联系QQ 1257123976 5-10元一份,必过