1、pom添加:
<!-- WebSocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、websocket服务
package com.****.project.park.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* WebSocket的操作类
*/
@Component
@Slf4j
/**
* html页面与之关联的接口
* var reqUrl = "http://localhost:8081/websocket/" + cid;
* socket = new WebSocket(reqUrl.replace("http", "ws"));
*/
@ServerEndpoint("/websocket/voice")
public class WebSocketServer {
/**
* 静态变量,用来记录当前在线连接数,线程安全的类。
*/
private static AtomicInteger onlineSessionClientCount = new AtomicInteger(0);
/**
* 存放所有在线的客户端
*/
private static Map<String, Session> onlineSessionClientMap = new ConcurrentHashMap<>();
/**
* 连接建立成功调用的方法。由前端<code>new WebSocket</code>触发
*
* @param session 与某个客户端的连接会话,需要通过它来给客户端发送消息
*/
@OnOpen
public void onOpen(Session session) {
/**
* session.getId():当前session会话会自动生成一个id,从0开始累加的。
*/
log.info("连接建立中 ==> session_id = {}", session.getId());
//加入 Map中。将页面的sid和session绑定或者session.getId()与session
onlineSessionClientMap.put(session.getId(), session);
//在线数加1
onlineSessionClientCount.incrementAndGet();
sendToOne(session.getId(), "连接成功");
log.info("连接建立成功,当前在线数为:{} ==> 开始监听新连接:session_id = {}。", onlineSessionClientCount, session.getId());
}
/**
* 连接关闭调用的方法。由前端<code>socket.close()</code>触发
*
* @param session
*/
@OnClose
public void onClose(Session session) {
onlineSessionClientMap.remove(session.getId());
//在线数减1
onlineSessionClientCount.decrementAndGet();
log.info("连接关闭成功,当前在线数为:{} ==> 关闭该连接信息:session_id = {}。", onlineSessionClientCount, session.getId());
}
/**
* 收到客户端消息后调用的方法。由前端<code>socket.send</code>触发
* * 当服务端执行toSession.getAsyncRemote().sendText(xxx)后,前端的socket.onmessage得到监听。
*
* @param message
* @param session
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("服务端收到{}客户端消息 ==> message = {}",session.getId(), 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集合
onlineSessionClientMap.forEach((customId, toSession) -> {
log.info("服务端给客户端群发消息 ==> toSid = {}, message = {}", toSession.getId(), message);
toSession.getAsyncRemote().sendText(message);
});
}
/**
* 指定发送消息
*
* @param toSid
* @param message
*/
public void sendToOne(String toSid, String message) {
// 通过sid查询map中是否存在
Session toSession = onlineSessionClientMap.get(toSid);
if (toSession == null) {
log.error("服务端给客户端发送消息 ==> toSid = {} 不存在, message = {}", toSid, message);
return;
}
// 异步发送
log.info("服务端给客户端发送消息 ==> toSid = {}, message = {}", toSid, message);
toSession.getAsyncRemote().sendText(message);
}
}
3、对websocket开启白名单访问
4、nginx中配置支持websocket
location ^~/ws/ {
proxy_pass http://192.168.67.5:8083/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}