原文:https://huan1993.iteye.com/blog/2433552

最近在学习netty相关的知识,看到netty可以实现 websoket,因此记录一下在netty中实现websocket的步骤,主要实现传递文本消息传递二进制消息,传递二进制消息由于需要传递额外信息,因此使用自定义消息协议。

需求:

1、使用 netty 实现 websocket 服务器

    2、实现 文本信息 的传递

    3、实现 二进制 信息的传递,如果是图片则传递到后台后在前台直接显示,非图片提示。(此处的图片和非图片是前端传递到后台的二进制数据然后后端在原封不动的直接返回到前台)

    4、只需要考虑 websocket 协议,不用处理http请求

实现细节:

1、netty中对websocket增强的处理器

WebSocketServerProtocolHandler 

>> 此处理器可以处理了 webSocket 协议的握手请求处理,以及 ClosePingPong控制帧的处理。对于文本和二进制的数据帧需要我们自己处理

>> 如果我们需要拦截 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、主要的依赖

  1. <dependency>
  2. <groupId>io.netty</groupId>
  3. <artifactId>netty-all</artifactId>
  4. <version>4.1.31.Final</version>
  5. </dependency>

2、webSocket服务端编写

  1. @Slf4j
  2. public class WebSocketServer {
  3. public static void main(String[] args) throws InterruptedException {
  4. EventLoopGroup bossGroup = new NioEventLoopGroup();
  5. EventLoopGroup workGroup = new NioEventLoopGroup();
  6. try {
  7. ServerBootstrap bootstrap = new ServerBootstrap();
  8. bootstrap.group(bossGroup, workGroup)
  9. .option(ChannelOption.SO_BACKLOG, 128)
  10. .childOption(ChannelOption.TCP_NODELAY, true)
  11. .childOption(ChannelOption.SO_KEEPALIVE, true)
  12. .handler(new LoggingHandler(LogLevel.TRACE))
  13. .channel(NioServerSocketChannel.class)
  14. .childHandler(new ChannelInitializer<SocketChannel>() {
  15. @Override
  16. protected void initChannel(SocketChannel ch) throws Exception {
  17. ch.pipeline()
  18. .addLast(new LoggingHandler(LogLevel.TRACE))
  19. // HttpRequestDecoder和HttpResponseEncoder的一个组合,针对http协议进行编解码
  20. .addLast(new HttpServerCodec())
  21. // 分块向客户端写数据,防止发送大文件时导致内存溢出, channel.write(new ChunkedFile(new File("bigFile.mkv")))
  22. .addLast(new ChunkedWriteHandler())
  23. // 将HttpMessage和HttpContents聚合到一个完成的 FullHttpRequest或FullHttpResponse中,具体是FullHttpRequest对象还是FullHttpResponse对象取决于是请求还是响应
  24. // 需要放到HttpServerCodec这个处理器后面
  25. .addLast(new HttpObjectAggregator(10240))
  26. // webSocket 数据压缩扩展,当添加这个的时候WebSocketServerProtocolHandler的第三个参数需要设置成true
  27. .addLast(new WebSocketServerCompressionHandler())
  28. // 服务器端向外暴露的 web socket 端点,当客户端传递比较大的对象时,maxFrameSize参数的值需要调大
  29. .addLast(new WebSocketServerProtocolHandler("/chat", null, true, 10485760))
  30. // 自定义处理器 - 处理 web socket 文本消息
  31. .addLast(new TextWebSocketHandler())
  32. // 自定义处理器 - 处理 web socket 二进制消息
  33. .addLast(new BinaryWebSocketFrameHandler());
  34. }
  35. });
  36. ChannelFuture channelFuture = bootstrap.bind(9898).sync();
  37. log.info("webSocket server listen on port : [{}]", 9898);
  38. channelFuture.channel().closeFuture().sync();
  39. } finally {
  40. bossGroup.shutdownGracefully();
  41. workGroup.shutdownGracefully();
  42. }
  43. }
  44. }

注意:

1、看一下上方依次引入了哪些处理器

2、对于 webSocket 的握手、Close、Ping、Pong等的处理,由 WebSocketServerProtocolHandler 已经处理了,我们自己只需要处理 Text和Binary等数据帧的处理。

3、对于传递比较大的文件,需要修改 maxFrameSize 参数。

3、自定义处理器握手后和文本消息

netty实现websocket发送文本和二进制数据的更多相关文章

  1. 【python】3.x,string与bytes的区别(文本,二进制数据)

    Python 3对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示, 二进制数据则由bytes类型表示. 不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也 ...

  2. 前端如何接收 websocket 发送过来的实时数据

    WebSocket protocol 是HTML5一种新的协议,它实现了浏览器与服务器全双工通信(full-duple).刚开始的握手需要借助HTTP请求完成,在 WebSocket API,浏览器和 ...

  3. 详细解读XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度

    本文主要参考:MDN 分析并操作 responseXML属性 如果你使用 XMLHttpRequest 来获得一个远程的 XML 文档的内容,responseXML 属性将会是一个由 XML 文档解析 ...

  4. IO流-文本IO\读写二进制数据

    文本IO 一.简述 OutputStreamWriter类使用选定的编码方式吧Unicode字符流转换为字节流,InputStreamReader类将包含字节的输入流转为可以产生Unicode字符的读 ...

  5. Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

    目录 SignalR系列目录(注意,是ASP.NET的目录.不是Core的) 前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于Signal ...

  6. 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据

    [源码下载] 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 读写文本数 ...

  7. Java模拟POST请求发送二进制数据

    在进行程序之间数据通信时我们有时候就需要自定义二进制格式,然后通过HTTP进行二进制数据交互.交互的示例代码如下: public static void main(String[] args) { S ...

  8. Hibernate 中 联合主键映射 组合关系映射 大对象映射(或者说文本大对象,二进制数据大对象)

    Clob:文本大对象,最长4G Blob:二进制数据大对象,最长4G util: public class HibUtil { private static SessionFactory sessio ...

  9. [ActionScript 3.0] AS利用ByteArray向PHP发送二进制数据生成图片

    flash as3向php发送二进制数据,通过php保存成图片. AS端: package { import com.JPEGEncoder.JPGEncoder; import flash.disp ...

随机推荐

  1. [简短问答]LODOP套打问题及相关

    该博文为简短问答,具体详细介绍可查看本博客的相关博文,套打及位置相关详细博文:LODOP中的各种宽高和位置简短问答.LODOP不同打印机出现偏移问题.Lodop打印控件打印机可打区域的影响 设置纸张边 ...

  2. [LeetCode] 216. Combination Sum III 组合之和 III

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  3. ECS与EDAS什么意思?

    1.ECS 英文:Elastic Compute Service  简称云服务器 2.EDAS英文:Enterprise Distributed Application Service   企业级分布 ...

  4. 消息发送函数OSMboxPostOpt()

    消息发送函数OSMboxPostOpt() 作用,ucos 3中的消息邮箱,具有广播功能,发送一条消息就可以使所有等待该消息的任务进入就绪状态,从而完成消息分发功能,具有一个消息唤醒多个任务的机制.

  5. kubernetes-subpath用法(把文件挂载在已存在的目录下,不覆盖原目录)

    以ngxin的配置文件为例子: nginx-deployment.yaml : apiVersion: v1 kind: ConfigMap metadata: name: nginx-cm data ...

  6. Python 内置函数--range() xrange()

    >>>xrange(8) xrange(8) >>> list(xrange(8)) [0, 1, 2, 3, 4, 5, 6, 7] >>> r ...

  7. Django-model更上层楼

    一 QuerySet对象 1.1可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET子句. Entry.objects.all()[:5] # ( ...

  8. gin - 读取Body后再次赋值

    这样就不影响后面读取了

  9. hadoop 异常

    2019-09-20 22:49:51,955 WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Problem connecting to ...

  10. Spring Boot 五种热部署方式

    [推荐]2019 Java 开发者跳槽指南.pdf(吐血整理)>>> 1.模板热部署 在SpringBoot中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不 ...