1、maven項目,第一步需要配置jar包
org.springframework.boot
spring-boot-starter-websocket
2、前臺使用
var websocket = null;
//判斷當前瀏覽器是否支持WebSocket
if('WebSocket' in window){
//連接WebSocket節點
websocket = new WebSocket("
ws://localhost:81/api/imserver/"+用戶id;);
}else{
console.log("您的瀏覽器不支持WebSocket");
}
//連接發生錯誤的回調方法
websocket.onerror = function(){
};
//連接成功建立的回調方法
websocket.onopen = function(event){
}
//接收到消息的回調方法
websocket.onmessage = function(event){
setMessageInnerHTML(event.data);
}
//連接關閉的回調方法
websocket.onclose = function(){
}
//發送消息
function send(){
var message = document.getElementById('text').value;
websocket.send(message);
}
窗口關閉或者退出登錄時調用,如果掛掉需要重新請求
//監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
window.onbeforeunload = function(){
websocket.close();
}
前臺檢測後臺是否掛掉
//針對斷網的情況的心跳重連
var heartCheck = {
timeout: 20000,//20ms
timeoutObj: null,
reset: function( ){
clearTimeout(this.timeoutObj);
this.start();
},
start: function( ){
this.timeoutObj = setTimeout(function(){
websocket.send("HeartBeat"); //自定義需要執行的命令
}, this.timeout)
}
};
heartCheck.start();
heartCheck.reset();
//將消息顯示在網頁上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += innerHTML + '
';
}
3、後臺使用
新建WebSocketConfig 類
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
新建WebSocketServer類
@ServerEndpoint(value="/imserver/{userId}")
@Component
public class WebSocketServer {
private final static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
/**靜態變量,用來記錄當前在線連接數。應該把它設計成線程安全的。*/
private static int onlineCount = 0;
/**concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。*/
private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
/**與某個客戶端的連接會話,需要通過它來給客戶端發送數據*/
private Session session;
/**接收userId*/
private String userId="";
/**
* 連接建立成功調用的方法
**/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
this.session = session;
this.userId=userId;
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
webSocketMap.put(userId,this);
//加入set中
}else{
webSocketMap.put(userId,this);
//加入set中
addOnlineCount();
//在線數加1
}
log.info("用戶連接:"+userId+",當前在線人數為:" + getOnlineCount());
try {
sendMessage("");
} catch (IOException e) {
log.error("用戶:"+userId+",網絡異常!!!!!!");
}
}
/**
* 連接關閉調用的方法
*/
@OnClose
public void onClose() {
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
//從set中刪除
subOnlineCount();
}
log.info("用戶退出:"+userId+",當前在線人數為:" + getOnlineCount());
}
/**
* 收到客戶端消息後調用的方法
*
* @param message 客戶端發送過來的消息*/
@OnMessage
public void onMessage(String message, Session session) {
//log.info("用戶消息:"+userId+",報文:"+message);
//可以群發消息
//消息保存到數據庫、redis
if(StringUtils.isNotBlank(message)){
try {
if("ping".equals(message)) {
webSocketMap.get(userId).sendMessage("pong");
}else {
//解析發送的報文
JSONObject jsonObject = JSON.parseObject(message);
//追加發送人(防止串改)
jsonObject.put("fromUserId",this.userId);
String toUserId=jsonObject.getString("toUserId");
//傳送給對應toUserId用戶的websocket
if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){
webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
}else{
log.error("請求的userId:"+toUserId+"不在該服務器上");
//否則不在這個服務器上,發送到mysql或者redis
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
/**
* 用戶錯誤
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用戶錯誤:"+this.userId+",原因:"+error.getMessage());
}
/**
* 實現服務器主動推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 發送自定義消息
* */
public static void sendInfo(String message,@PathParam("userId") String userId) {
try {
log.info("發送消息到:"+userId+",報文:"+message);
if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
webSocketMap.get(userId).sendMessage(message);
}else{
log.error("用戶"+userId+",不在線!");
}
} catch (Exception e) {
log.error("異常"+userId+",報文:"+message);
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
後臺使用時調用其發送方法,前臺就可以收到,然後修改頁面顯示
WebSocketServer.sendInfo("",userid);
謝謝觀看!!!