pom文件引入包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
配置文件application.properties
server.port=9886
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
WebSocketConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 開啓WebSocket支持
* @author zhengkai
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
WebSocketServer
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import lombok.extern.slf4j.Slf4j;
@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {
static Log log=LogFactory.get(WebSocketServer.class);
//靜態變量,用來記錄當前在線連接數。應該把它設計成線程安全的。
private static int onlineCount = 0;
//concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
//與某個客戶端的連接會話,需要通過它來給客戶端發送數據
private Session session;
//接收sid
private String sid="";
/**
* 連接建立成功調用的方法*/
@OnOpen
public void onOpen(Session session,@PathParam("sid") String sid) {
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在線數加1
log.info("有新窗口開始監聽:"+sid+",當前在線人數爲" + getOnlineCount());
this.sid=sid;
try {
sendMessage("連接成功");
} catch (IOException e) {
log.error("websocket IO異常");
}
}
/**
* 連接關閉調用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //從set中刪除
subOnlineCount(); //在線數減1
log.info("有一連接關閉!當前在線人數爲" + getOnlineCount());
}
/**
* 收到客戶端消息後調用的方法
*
* @param message 客戶端發送過來的消息*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到來自窗口"+sid+"的信息:"+message);
//羣發消息
for (WebSocketServer item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("發生錯誤");
error.printStackTrace();
}
/**
* 實現服務器主動推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 羣發自定義消息
* */
public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException {
log.info("推送消息到窗口"+sid+",推送內容:"+message);
for (WebSocketServer item : webSocketSet) {
try {
//這裏可以設定只推送給這個sid的,爲null則全部推送
if(sid==null) {
item.sendMessage(message);
}else if(item.sid.equals(sid)){
item.sendMessage(message);
}
} catch (IOException e) {
continue;
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
消息推送
@Controller
@RequestMapping("/checkcenter")
public class CheckCenterController {
//頁面請求
@GetMapping("/socket/{cid}")
public ModelAndView socket(@PathVariable String cid) {
ModelAndView mav=new ModelAndView("/socket");
mav.addObject("cid", cid);
return mav;
}
//推送數據接口
@ResponseBody
@RequestMapping("/socket/push/{cid}")
public ApiReturnObject pushToWeb(@PathVariable String cid,String message) {
try {
WebSocketServer.sendInfo(message,cid);
} catch (IOException e) {
e.printStackTrace();
return ApiReturnUtil.error(cid+"#"+e.getMessage());
}
return ApiReturnUtil.success(cid);
}
}
頁面發起socket請求
<script>
var socket;
if(typeof(WebSocket) == "undefined") {
console.log("您的瀏覽器不支持WebSocket");
}else{
console.log("您的瀏覽器支持WebSocket");
//實現化WebSocket對象,指定要連接的服務器地址與端口 建立連接
socket = new WebSocket("https://localhost:9886/websocket/20".replace("https","ws"));
//打開事件
socket.onopen = function() {
console.log("Socket 已打開");
//socket.send("這是來自客戶端的消息" + location.href + new Date());
};
//獲得消息事件
socket.onmessage = function(msg) {
console.log(msg.data);
//發現消息進入 開始處理前端觸發邏輯
};
//關閉事件
socket.onclose = function() {
console.log("Socket已關閉");
};
//發生了錯誤事件
socket.onerror = function() {
alert("Socket發生了錯誤");
//此時可以嘗試刷新頁面
}
//離開頁面時,關閉socket
//jquery1.8中已經被廢棄,3.0中已經移除
// $(window).unload(function(){
// socket.close();
//});
}
</script>
測試
打開頁面
https://localhost:9886/checkcenter/socket/20
postman get方式發送消息
https://localhost:9886/checkcenter/socket/push/20?message=“hello”
工具類:
ApiReturnObject
import java.io.Serializable;
public class ApiReturnObject implements Serializable{
private static final long serialVersionUID = 1L;
String errorCode="00";
Object errorMessage;
Object returnObject;
public ApiReturnObject(String errorCode, Object errorMessage, Object returnObject) {
super();
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.returnObject = returnObject;
}
public ApiReturnObject(Object errorMessage, Object returnObject) {
super();
this.errorMessage = errorMessage;
this.returnObject = returnObject;
}
public ApiReturnObject(Object returnObject) {
super();
this.returnObject = returnObject;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public Object getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(Object errorMessage) {
this.errorMessage = errorMessage;
}
public Object getReturnObject() {
return returnObject;
}
public void setReturnObject(Object returnObject) {
this.returnObject = returnObject;
}
}
ApiReturnUtil
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class ApiReturnUtil implements Serializable{
private static final long serialVersionUID = 1L;
public static ApiReturnObject error(Object errorMessage) {
System.out.println(errorMessage);
List<Object> object=new ArrayList<Object>();
return new ApiReturnObject("01",errorMessage,object);
}
public static ApiReturnObject error(Object errorMessage, Object returnObject) {
List<Object> object=new ArrayList<Object>();
object.add(returnObject);
return new ApiReturnObject("01",errorMessage,object);
}
public static ApiReturnObject success(Object returnObject) {
if(returnObject instanceof java.util.List){
return new ApiReturnObject("00","success",returnObject);
}else {
List<Object> object=new ArrayList<Object>();
object.add(returnObject);
return new ApiReturnObject("00","success",object);
}
}
public static ApiReturnObject success(Object errorMessage, Object returnObject) {
if(returnObject instanceof java.util.List){
return new ApiReturnObject("00",errorMessage,returnObject);
}else {
List<Object> object=new ArrayList<Object>();
object.add(returnObject);
return new ApiReturnObject("00",errorMessage,object);
}
}
}
BasePath
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
public class BasePath {
protected static String contextPath = null;
protected static String basePath = null;
protected static String realPath = null;
public static String getBasePath(HttpServletRequest request) {
contextPath = request.getContextPath();
basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+contextPath+"/";
return basePath;
}
public static String getRealPath(HttpServletRequest request, String path) {
ServletContext context = request.getSession().getServletContext();
realPath = context.getRealPath(path);
realPath = context.getRealPath(path)+"\\";
return realPath;
}
public static String getMyRealPath(HttpServletRequest request, String path) {
ServletContext context = request.getSession().getServletContext();
realPath = context.getRealPath(path);
realPath = context.getRealPath(path);
return realPath;
}
}
本章屬於學習後自總結,原文章參考:https://blog.csdn.net/moshowgame/article/details/80017979