SpringBoot Websocket
1、 pom添加依赖
<!--websocket依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、添加bean注入
首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3、具体实现类
@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {
// 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
// concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet<WebSocketServer> webSocket = new CopyOnWriteArraySet<>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private String sid="";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid){
this.session = session;
webSocket.add(this);
addOnlineCount();
this.sid=sid;
try {
sendMessage("连接成功");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
webSocket.remove(this);
subOnlineCount();
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session){
for (WebSocketServer item : webSocket){
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void sendInfo(String message,@PathParam("sid") String sid)throws IOException {
System.out.println("接受到请求sid="+sid+"message="+message);
for (WebSocketServer item:webSocket){
try {
if(sid == null){
item.sendMessage(message);
}else if(item.sid.equals(sid)){
item.sendMessage(message);
}
} catch (IOException e) {
continue;
}
}
}
@OnError
public void onError(Session session, Throwable error){
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public static synchronized int getOnlineCount(){
return onlineCount;
}
public static synchronized void addOnlineCount(){
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount(){
WebSocketServer.onlineCount--;
}
}
4、前端调用
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>默认</title>
</head>
<body>
<h1>default</h1>
<script>
var socket;
if (typeof (WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket")
} else {
//本地ip
socket = new WebSocket("ws://localhost:8080/websocket/1");
socket.onopen = function (ev) {
console.log("socket 已经打开")
}
socket.onmessage = function (msg) {
debugger;
if (isJsonString(msg.data)) {
var result = JSON.parse(msg.data);
console.log(result.data);
console.log(result.code);
if (result.code == 'ok') {
userId = result.data;
location.href = "/index";
}
}
}
socket.onclose = function (ev) {
console.log("socket已经关闭")
}
socket.onerror = function (ev) {
alert("请求出错")
}
}
function isJsonString(str) {
try {
if (typeof JSON.parse(str) == "object") {
return true;
}
} catch (e) {
}
return false;
}
</script>
</body>
</html>
5、请求访问
@GetMapping("/test")
@ResponseBody
public void test() {
Map<String, String> resultMap = new HashMap<>();
resultMap.put("data", String.valueOf(1));
resultMap.put("code", "ok");
String msg = new Gson().toJson(resultMap);
try {
WebSocketServer.sendInfo(msg, "1");
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
}