什么是socket
Socket
是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket
其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket
接口后面,对用户来说,一组简单的接口就是全部,让Socket
去组织数据,以符合指定的协议
我们知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”
模式来操作。Socket(套接字)
用来描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发送请求或者应答网络请求。Socket是支持TCP/IP协议的网络通信的基础操作单元,是对网络通信过程中端点的抽象表示,包含了进行网络通信所必须的五种信息:
连接所使用的协议;
本地主机的IP地址;
本地远程的协议端口;
远地主机的IP地址;
远地进程的协议端口。
一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
websocket概念
WebSocket是一种在单个TCP
连接上进行全双工通信的协议,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
实现思路
我们知道,前端与服务端建立websocket后,后端需要向对应的websocket推送数据,而在分布式环境中,服务端实例可能存在多个,因为微服务负载均衡导致不同实例会有各自的websocket连接,因而实例A无法推送数据到实例B中的websocket连接。这里利用redis的消息订阅做websocket的转发,每个建立的ws与key绑定,但推送数据时会根据key到redis转发到相应实例进行ws推送
关键代码
基于org.springframework
的spring-websocket
开发
1 | <dependency> |
用redis做转发
项目启动后BrokerHelper.java
会执行定时任务,会到redis中缓存该实例的信息,并做心跳的判断
1 |
|
缓存WebSocketSession及与key的关系
DefaultRelationshipDefining.java
缓存webSocketSession与key的关系
1 | private Map<String, Set<WebSocketSession>> keySessionsMap = new ConcurrentHashMap<>(); |
消息推送与redis订阅
DefaultSmartMessageSender.java
中sendByKey()
推送消息给webSocketSession
1 |
|
订阅redis‘Topic
ChoerodonWebSocketConfigure.java(实现WebSocketConfigurer接口)
中监听redis订阅
1 |
|
1 | /** |
参考文献
- choerodon-starter-websocket