1. 准备工作
1. 依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. 配置类
java
/**
* WebSocket配置类。开启WebSocket的支持
*/
@Configuration
public class WebSocketConfig {
/**
* bean注册:会自动扫描带有@ServerEndpoint注解声明的Websocket Endpoint(端点),注册成为Websocket bean。
* 要注意,如果项目使用外置的servlet容器,而不是直接使用springboot内置容器的话,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2. @ServerEndpoint
java
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* WebSocket的操作类
*/
@Component
@Slf4j
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {
// 存放会话对象
private static Map<String, Session> sessionMap = new HashMap();
/**
* 连接建立成功调用的方法。
*
* @param sid 每次页面建立连接时传入到服务端的id,比如用户id等。可以自定义。
* @param session 与某个客户端的连接会话,需要通过它来给客户端发送消息
*/
@OnOpen
public void onOpen(@PathParam("sid") String sid, Session session) {
log.info("连接建立中 ==> session = {}, sid = {}", session, sid);
//加入 Map中
// 在这里可以将用户id与session绑定,发送消息时通过用户id就能给特定用户发送消息
sessionMap.put(sid, session);
}
/**
* 连接关闭调用的方法。
*
* @param sid
* @param session
*/
@OnClose
public void onClose(@PathParam("sid") String sid, Session session) {
log.info("连接关闭中 ==> session = {}, sid = {}", session, sid);
// 从 Map中移除
sessionMap.remove(sid);
}
/**
* 收到客户端消息后调用的方法。由前端<code>socket.send</code>触发
* * 当服务端执行toSession.getAsyncRemote().sendText(xxx)后,前端的socket.onmessage得到监听。
*/
@OnMessage
public void onMessage(@PathParam("sid") String sid, String message) {
log.info("服务端收到客户端消息 ==> Sid = {}, message = {}", sid, message);
}
/**
* 发生错误调用的方法
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("WebSocket发生错误,错误信息为:" + error.getMessage());
error.printStackTrace();
}
/**
* 群发消息
* @param message 消息
*/
public void sendToAll(String message) {
// 将map集合中的value值,提取出来,放入集合中
Collection<Session> sessions = sessionMap.values();
for (Session session : sessions) {
try {
//服务器向客户端发送消息
session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4. 调用webSocket
java
// 注入webSocketServer对象
@Autowired
private WebSocketServer webSocketServer;
// 方法中使用
webSocketServer.sendToAll(JSON.toJSONString(map));
4. 前端发送
前端发送的url:ws://localhost:8080/ws/999
nginx中配置:
conf
# WebSocket
location /ws/ {
proxy_pass http://localhost:8080/ws/;
proxy_http_version 1.1;
proxy_read_timeout 3600s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}