1、加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
2、编写配置类:开启WebSocket服务端的自动注册。
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
注意:ServerEndpointExporter 是由Spring官方提供的标准实现,用于扫描ServerEndpointConfig配置类和@ServerEndpoint注解实例。使用规则也很简单:1.如果使用默认的嵌入式容器 比如Tomcat则必须手工在上下文提供ServerEndpointExporter。2. 如果使用外部容器部署war包,则不要提供提供ServerEndpointExporter,因为此时SpringBoot默认将扫描服务端的行为交给外部容器处理
3、创建WebSocket服务端
- 通过注解
@ServerEndpoint 来声明实例化WebSocket服务端。(注意配置@Component 才能被spring扫描) - 通过注解
@OnOpen 、@OnMessage 、@OnClose 、@OnError 来声明回调函数。
事件类型 | WebSocket服务端注解 | 事件描述 |
---|
open | @OnOpen (Session session) | 当打开连接后触发 | message | @OnMessage(Session session,String message) | 当客户端接收服务端数据时触发 | error | @OnClose(Session session) | 当通信异常时触发 | close | @OnError(Session session,Throwable error) | 当连接关闭时触发 |
- 发送消息:
new Session().getBasicRemote().sendText(message);
示例代码如下:
package com.test.service.server;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson;
import com.test.model.repose.Leaderboard;
import com.test.model.request.BasePaginationQuery;
import com.test.service.SubmissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
@Slf4j
@Component
@ServerEndpoint(value = "/websocket/{id}")
public class WebSocketServer {
public static CopyOnWriteArraySet<WebSocketServer> webSocketServerSet
= new CopyOnWriteArraySet<>();
private static int onlineCount = 0;
private static SubmissionService submissionService;
private Session session;
private String id = "";
public static synchronized int getOnlineCount() {
return onlineCount;
}
@Autowired
public void setSubmissionService(SubmissionService submissionService) {
WebSocketServer.submissionService = submissionService;
}
@PostConstruct
public void init() {
log.info("websocket 加载");
}
@OnOpen
public void onOpen(Session session, @PathParam("id") String id) {
log.info("onOpen >> 链接成功");
this.session = session;
webSocketServerSet.add(this);
addOnlineCount();
log.info("有新窗口开始监听:" + id + ", 当前在线人数为:" + getOnlineCount());
this.id = id;
try {
BasePaginationQuery basePaginationQuery = new BasePaginationQuery();
basePaginationQuery.setId(id);
IPage<Leaderboard> iPage = submissionService.selectLeaderboardByCompetitionId(basePaginationQuery);
String data = new Gson().toJson(iPage.getRecords());
sendMessage(data);
} catch (Exception e) {
log.error(e.toString());
}
}
@OnClose
public void onClose() {
log.info("onClose >> 链接关闭");
webSocketServerSet.remove(this);
subOnLineCount();
log.info("链接关闭,当前在线人数:" + getOnlineCount());
}
@OnMessage
public void onMessage(String message) {
log.info("接收到窗口:" + id + " 的信息:" + message);
for (WebSocketServer webSocketServer : webSocketServerSet) {
try {
BasePaginationQuery basePaginationQuery = new BasePaginationQuery();
basePaginationQuery.setId(id);
IPage<Leaderboard> iPage = submissionService.selectLeaderboardByCompetitionId(basePaginationQuery);
String data = new Gson().toJson(iPage.getRecords());
webSocketServer.sendMessage(data);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@OnError
public void onError(Session session, Throwable e) {
e.printStackTrace();
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public void broadCastInfo(String message) throws IOException {
for (WebSocketServer webSocketServer : webSocketServerSet) {
if (webSocketServer.session.isOpen()) {
webSocketServer.sendMessage(message);
}
}
}
private void subOnLineCount() {
WebSocketServer.onlineCount--;
}
private void addOnlineCount() {
WebSocketServer.onlineCount++;
}
}
4、在线测试 工具:http://www.easyswoole.com/wstool.html
|