WebSocket简述
- WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
- WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
- 在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
- 现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
- HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
多屏联动方案(三屏为例)
1、方案说明
实现逻辑
- 每个屏幕(页面)都有对应的一个ws连接,一个标识,一个组标识
- 主屏在建立连接之前需要调用接口获取一个唯一标识符即组id
- 每个屏幕在建立ws连接时都需要传值:屏幕标识&组标识
- 后台将三个ws连接根据组标识绑定为一组
- 三个ws连接为一组,互相通信,实现联动
步骤图解
2、环境说明
版本
- SpringBoot 2.1.5.RELEASE
- spring-boot-starter-websocket 2.1.5.RELEASE
- jdk1.8
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
核心代码实现
配置websocket
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @Author :feiyang
* @Date :Created in 4:03 PM 2019/9/18
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter (){
return new ServerEndpointExporter();
}
}
将会话存储至内存
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import javax.websocket.Session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author feiyang
*/
public class SessionStorage {
private Map<String, Map<String, Session>> sessionStore = new ConcurrentHashMap<>();
private static volatile SessionStorage storage;
private static final Logger logger = LoggerFactory.getLogger(SessionStorage.class);
private SessionStorage() {
}
public static synchronized SessionStorage getInstance() {
if(storage == null) {
synchronized(SessionStorage.class) {
if(storage == null) {
storage = new SessionStorage();
}
}
}
return storage;
}
/**
* 将ws连接会话分组保存
* @author feiyang
* @param session
* @param wsGroupId
* @param type
* @return void
* @date 2019/9/19
* @throws
*/
public void putSession(Session session, String wsGroupId, String type) {
if(session != null) {
Map<String, Session> sessionGroup = this.sessionStore.get(wsGroupId);</