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 ...
随机推荐
- springboot 整合Elasticsearch
Elasticsearch Elasticsearch 是一个分布式.可扩展.实时的搜索与数据分析引擎. 它能从项目一开始就赋予你的数据以搜索.分析和探索的能力,可用于实现全文搜索和实时数据统计. 在 ...
- [LeetCode] 70. Climbing Stairs 爬楼梯
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- 禅道的使用—bug管理工具
简介 禅道项目管理软件集产品管理.项目管理.质量管理.文档管理.组织管理和事务管理于一体,是一款功能完备的项目管理软件,完美地覆盖了项目管理的核心流程. 1.禅道使用的基本流程 禅道管理软件中,核心的 ...
- Postman 使用方法详细介绍
1,下载安装: https://www.getpostman.com/apps 2,打开Postman,如图所示: 3,创建一个接口项目 4,新增接口文件 5,下面以登录接口login为例,介绍如何做 ...
- 03 Mybatis框架---学习笔记1--框架的概念及优势
1.框架的概念 框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统.简单说就是使用别人搭好的舞台,你来做表演.而且,框架一般是成熟的,不断升级的软件.框架是我们软件开发中的一套解决方 ...
- [转帖]IBM报告:多国央行考虑发行数字货币 最快5年内问世
IBM报告:多国央行考虑发行数字货币 最快5年内问世 https://news.cnblogs.com/n/646001/ DCEP 中国央行可能是第一家发布 数字货币的央行 DCEP 是基于 UTX ...
- [转帖]华为一枝独秀!Q3国内智能手机出货量公布:Ov、小米、iPhone侧目
华为一枝独秀!Q3国内智能手机出货量公布:Ov.小米.iPhone侧目 https://news.cnblogs.com/n/645880/ 华为真生猛.. 作者:花生酱 国内手机市场份额争夺激烈,你 ...
- c++ map容器使用及问题
C++ STL库map容器一些总结,欢迎大家指正补充. map容器由两部分组成,分别为关键字(Key)和值(Value),关键字和值都可以声明为任意类型的数据,注意:关键字唯一,不能重复!使用需包含头 ...
- Weave跨主机实现docker互通,固定ip及dns使用介绍
一.weave介绍Weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,现在就采用它来实现Docker多宿主机互联的目的,它能够创建一个虚拟网络,用于连接部署在多台主机上的 ...
- day39——SQL语句简单介绍、库、表、记录、安装mysql简单命令
day39 SQL语句简单介绍 库(增删改查) 查看数据库 show databases; 查看其中一个库 show create database db1; 创建数据库 create databas ...