Netty Starter
Netty:https://gitee.com/Yeauty/netty-websocket-spring-boot-starter
注意
服务端主动关闭连接,服务端也会接收到连接关闭的回调。
依赖
基于Netty的Websocket的框架
1 | <dependency> |
代码
添加新类
1 | import io.netty.handler.codec.http.HttpHeaders; |
接下来即可在application.properties
中配置
1 | ws.path=/ |
用户标记
我们可以在onMessage中绑定业务逻辑中的ID
1 | session.setAttribute("userId", userId); |
在onMessage
、onError
、onClose
时我们可用重新取到之前绑定的值,进行业务逻辑处理。
1 | session.getAttribute("userId") |
onClose
移除时
1 | //获取存储的session |
之所以要判断msession.isActive()
是防止用户短时间重连、断开重连、其它设备登录时msession已经被更新,msession.getAttribute("device").equals(device)
是为了防止其它设备登录时msession已经被更新。
发送消息时
1 | Session msession = xxx; |
t-io Starter
t-io官方示例:https://gitee.com/psvmc/tio-websocket-showcase
官方文档:https://www.tiocloud.com/doc/tio/318?pageNumber=1
注意
不建议使用该库了,因为客户端长时间断网,服务端也收不到连接关闭的回调,这样有些业务逻辑就没法实现。
使用t-io的时候一定要注意
- 客户端一定不要发送空的消息,只要发送空消息,客户端会直接断开连接,并且服务端收不到断开的事件。
- 不支持ws地址后缀path的设置。
- 服务端主动关闭连接,服务端不会接收到连接关闭的回调。
- 客户端长时间断网,服务端也收不到连接关闭的回调。
依赖
删除原有的starter添加t-io的starter
1 | <properties> |
代码示例
主类
1 | import org.springframework.boot.SpringApplication; |
主要就是添加了
@EnableTioWebSocketServer
消息监听
1 | import org.springframework.stereotype.Component; |
给对应的客户端发送消息
1 | Tio.send(channelContext, WsResponse.fromText(msg, "utf-8")); |
接下来即可在application.properties
中配置
1 | tio.websocket.server.port=8888 |
发送消息
1 | // 单发 |
业务绑定
方式1 静态方法绑定
1 | // 用户ID |
方式2 对象属性绑定
1 | // 绑定用户ID |
方式3 对象属性绑定
1 | channelContext.set("userid", 123); |
SSL配置
配置
1 | tio.websocket.ssl.enabled=true |
证书生成
下载SSL证书
如果是阿里云申请的SSL证书,下载tomcat版本的,里面会有cert.pfx和password.txt
生成jks证书
添加Java到环境变量的Path中
D:\Program Files\Java\jdk1.8.0_102\bin
执行
1 | keytool -importkeystore -srckeystore .\cert.pfx -destkeystore .\cert-psvmc.jks -srcstoretype PKCS12 -deststoretype JKS |
输入两次新口令,再输入一次下载时带的密码文件中的密码就会生成文件cert-psvmc.jks
,我们在配置时用我们设置的新口令。
集群
集群添加如下配置
集群是通过redis的Pub/Sub实现,所以需要配置Redis
1 | tio.websocket.cluster.enabled=false |
SpringBoot Starter
这是SpringBoot官方提供的Webscoket框架
1 | <dependency> |
具体代码
1 | import org.springframework.context.annotation.Bean; |
WsServerEndpoint
1 | import java.io.IOException; |
说明:
这里有几个注解需要注意一下,首先是他们的包都在 javax.websocket 下。并不是 spring 提供的,而 jdk 自带的,下面是他们的具体作用。
@ServerEndpoint
通过这个 spring boot 就可以知道你暴露出去的 ws 应用的路径,有点类似我们经常用的@RequestMapping。比如你的启动端口是8080,而这个注解的值是ws,那我们就可以通过 ws://127.0.0.1:8888/ws 来连接你的应用
@OnOpen
当 websocket 建立连接成功后会触发这个注解修饰的方法,注意它有一个 Session 参数
@OnClose
当 websocket 建立的连接断开后会触发这个注解修饰的方法,注意它有一个 Session 参数
@OnMessage
当客户端发送消息到服务端时,会触发这个注解修改的方法,它有一个 String 入参表明客户端传入的值
@OnError
当 websocket 建立连接时出现异常会触发这个注解修饰的方法,注意它有一个 Session 参数
另外一点就是服务端如何发送消息给客户端,服务端发送消息必须通过上面说的 Session 类,通常是在@OnOpen 方法中,当连接成功后把 session 存入 Map 的 value,key 是与 session 对应的用户标识,当要发送的时候通过 key 获得 session 再发送,这里可以通过 session.getBasicRemote().sendText() 来对客户端发送消息。
接下来即可在application.properties
中配置
1 | server.port=8888 |
Netty原生
Netty简介
那么Netty到底是何方神圣?
- 用一句简单的话来说就是:Netty封装了JDK的NIO,让你用得更爽,你不用再写一大堆复杂的代码了。
- 用官方正式的话来说就是:Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。
下面是我总结的使用Netty不使用JDK原生NIO的原因
- 使用JDK自带的NIO需要了解太多的概念,编程复杂
- Netty底层IO模型随意切换,而这一切只需要做微小的改动,改改参数,Netty可以直接从NIO模型变身为IO模型
- Netty自带的拆包解包,异常检测等机制让你从NIO的繁重细节中脱离出来,让你只需要关心业务逻辑
- Netty解决了JDK的很多包括空轮询在内的bug
- Netty底层对线程,selector做了很多细小的优化,精心设计的reactor线程模型做到非常高效的并发处理
- 自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手
- Netty已经历各大rpc框架,消息中间件,分布式通信中间件线上的广泛验证,健壮性无比强大
Websocket服务端
引入Netty
1 | <dependency> |
初始化代码
1 | private static void initWebScoket() { |
bossGroup
对应接受新连接线程,主要负责创建新连接wokerGroup
对应负责读取数据的线程,主要用于读取数据以及业务逻辑处理
WebSocketHandle
1 | import io.netty.buffer.Unpooled; |
Websocket客户端
这样在JS中既可以这样连接
1 | var socket = new WebSocket("ws://127.0.0.1:8899/ws"); |
客户端测试
HTML
1 |
|
JS
1 | let timeunix = 0; |
注意
客户端一定不要发送空的消息,只要发送空消息,如果使用t-io,客户端会直接断开连接,并且服务端收不到断开的事件。
Maven依赖无法下载
比如我要下载的包为tio-websocket-server
到中央仓库地址:http://mvnrepository.com/
搜索到的依赖为
1 | <dependency> |
对应的地址为
https://mvnrepository.com/artifact/org.t-io/tio-websocket-server/3.7.1.v20210106-RELEASE
输入命令 需要修改的 url、groupId、artifactId、version
mvn dependency:get -DremoteRepositories=url -DgroupId=groupId -DartifactId=artifactId -Dversion=version
即
mvn dependency:get -DremoteRepositories=https://mvnrepository.com/artifact/org.t-io/tio-websocket-server -DgroupId=org.t-io -DartifactId=tio-websocket-server -Dversion=3.7.1.v20210106-RELEASE