SpringBoot整合WebSocket實現三種模式發送消息


1. 簡介

  WebSocket是HTML5開始提供的一種在單個TCP連接上進行全雙工通訊的協議。
  WebSocket的出現是為了解決Http協議只能在客戶端發送請求后服務端響應請求的問題,它允許服務端主動向客戶端發送請求。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,並進行雙向數據傳輸。
  在大多數情況下,為了實現消息推送,往往采用Ajax輪詢方式,它遵循的是Http協議,在特定的時間內向服務端發送請求,Http協議的請求頭較長,可能僅僅需要獲取較小的數據而需要攜帶較多的數據,而且對於消息不是特別頻繁的時候,大部分的輪詢都是無意的,造成了極大的資源浪費。
  HTML5定義的WebSocket協議,能更好的節省服務器資源和帶寬,並且能夠更實時地進行通訊。

2. 本文簡要

  本文基於SpringBoot框架整合WebSocket,實現三種模式發送消息:

  • 自己給自己發送消息
  • 自己給其他用戶發送消息
  • 自己給指定用戶發送消息

3. 示例代碼

  • 創建工程
  • 修改pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.c3stones</groupId>
	<artifactId>spring-boot-websocket-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-websocket-demo</name>
	<description>Spring Boot WebSocket Demo</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.8.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.4.1</version>
		</dependency>
		<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>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
  • 創建配置文件
      在resources目錄下創建application.yml。
server:
  port: 8080
  
spring:
  thymeleaf:
    prefix: classpath:/view/
    suffix: .html
    encoding: UTF-8
    servlet:
      content-type: text/html
    # 生產環境設置true
    cache: false  
  • 添加WebSocket配置類
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * WebSocket配置類
 * 
 * @author CL
 *
 */
@Configuration
public class WebSocketConfig {

	/**
	 * 注入ServerEndpointExporter
	 * <p>
	 * 該Bean會自動注冊添加@ServerEndpoint注解的WebSocket端點
	 * </p>
	 * 
	 * @return
	 */
	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
		return new ServerEndpointExporter();
	}

}
  • 創建啟動類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 啟動類
 * 
 * @author CL
 *
 */
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}

3.1 自己給自己發送消息
  • 創建服務端點
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

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 lombok.extern.slf4j.Slf4j;

/**
 * <b style="color: blue"> 自己給自己發送消息 </b>
 * 
 * @author CL
 *
 */
@Slf4j
@Component
@ServerEndpoint(value = "/selfToSelf")
public class SelfToSelfServer {

	/**
	 * 在線數
	 * <p>
	 * 多線程環境下,為了保證線程安全
	 * </p>
	 */
	private static AtomicInteger online = new AtomicInteger(0);

	/**
	 * 建立連接
	 * 
	 * @param session 客戶端連接對象
	 */
	@OnOpen
	public void onOpen(Session session) {
		// 在線數加1
		online.incrementAndGet();
		log.info("客戶端連接建立成功,Session ID:{},當前在線數:{}", session.getId(), online.get());
	}

	/**
	 * 接收客戶端消息
	 * 
	 * @param message 客戶端發送的消息內容
	 * @param session 客戶端連接對象
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		log.info("服務端接收消息成功,Session ID:{},消息內容:{}", session.getId(), message);

		// 處理消息,並響應給客戶端
		this.sendMessage(message, session);
	}

	/**
	 * 處理消息,並響應給客戶端
	 * 
	 * @param message 客戶端發送的消息內容
	 * @param session 客戶端連接對象
	 */
	private void sendMessage(String message, Session session) {
		try {
			String response = "Server Response ==> " + message;
			session.getBasicRemote().sendText(response);

			log.info("服務端響應消息成功,接收的Session ID:{},響應內容:{}", session.getId(), response);
		} catch (IOException e) {
			log.error("服務端響應消息異常:{}", e.getMessage());
		}
	}

	/**
	 * 關閉連接
	 * 
	 * @param session 客戶端連接對象
	 */
	@OnClose
	public void onClose(Session session) {
		// 在線數減1
		online.decrementAndGet();
		log.info("客戶端連接關閉成功,Session ID:{},當前在線數:{}", session.getId(), online.get());
	}

	/**
	 * 連接異常
	 * 
	 * @param session 客戶端連接對象
	 * @param error   異常
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("連接異常:{}", error);
	}

}
  • 創建測試頁面
      在resource下創建views文件夾,並創建測試頁面selfToSelfClient.html:
<!DOCTYPE HTML>
<html>
<head>
	<title>WebSocket - Self To Self</title>
</head>
<body>
	<input id="message" type="text" />
    <button onclick="sendMessage()">發送</button>
    <button onclick="closeWebSocket()">關閉</button>
    <hr/>
    <div id="response"></div>
</body>
<script type="text/javascript">
	var websocket = null;
	
	// 判斷當前瀏覽器是否支持WebSocket
	if ('WebSocket' in window) {
	    websocket = new WebSocket("ws://localhost:8080/selfToSelf");
	} else {
	    alert("當前瀏覽器不支持WebSocket");
	}
	
	// 建立連接成功時的回調方法
    websocket.onopen = function (event) {
    	printMessage("green", "建立連接成功!!!");
    }
	
	// 連接異常時的回調方法
    websocket.onerror = function (event) {
    	printMessage("red", "連接異常!!!");
    };

    // 客戶端接收消息時的回調方法
    websocket.onmessage = function (event) {
    	printMessage("blue", event.data);
    }

    // 關閉連接時的回調方法
    websocket.onclose = function() {
    	printMessage("yellow", "關閉連接成功!!!");
    }

    // 監聽窗口關閉事件,當窗口關閉時,主動關閉連接,防止連接未斷開時關閉窗口,服務端拋出異常
    window.onbeforeunload = function() {
        websocket.close();
    }
    
    // 發送消息
    function sendMessage() {
    	if (websocket.readyState != 1) {
    		printMessage("red", "未建立連接或者連接已處於關閉狀態!");
    	} else {
    		 var message = document.getElementById('message').value;
    	     websocket.send(message);
    	}
    }
    
 	// 關閉連接
    function closeWebSocket() {
        websocket.close();
    }
 	
  	// 打印消息
    function printMessage(color, text) {
        document.getElementById("response").innerHTML += "<font color='" + color +"'>" + text + "</font><br/>";
    }
</script>
</html>
  • 創建跳轉頁面Controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 頁面視圖Controller
 * 
 * @author CL
 *
 */
@Controller
public class ViewController {

	/**
	 * 跳轉到<b> 自己給自己發送消息 </b>頁面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/selfToSelf")
	public String selfToSelf() {
		return "selfToSelfClient";
	}

}
  • 測試
    2020-12-29 19:21:39.916  INFO 1096 --- [nio-8080-exec-2] com.c3stones.server.SelfToSelfServer     : 客戶端連接建立成功,Session ID:0,當前在線數:1
    2020-12-29 19:21:43.564  INFO 1096 --- [nio-8080-exec-3] com.c3stones.server.SelfToSelfServer     : 服務端接收消息成功,Session ID:0,消息內容:測試1
    2020-12-29 19:21:43.583  INFO 1096 --- [nio-8080-exec-3] com.c3stones.server.SelfToSelfServer     : 服務端響應消息成功,接收的Session ID:0,響應內容:Server Response ==> 測試1
    2020-12-29 19:21:45.290  INFO 1096 --- [nio-8080-exec-4] com.c3stones.server.SelfToSelfServer     : 客戶端連接關閉成功,Session ID:0,當前在線數:0    
    
    • 瀏覽器截圖
3.2 自己給其他用戶發送消息
  • 創建服務端點
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

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 lombok.extern.slf4j.Slf4j;

/**
 * <b style="color: blue"> 自己給其他用戶發送消息 </b>
 * 
 * @author CL
 *
 */
@Slf4j
@Component
@ServerEndpoint(value = "/selfToOther")
public class SelfToOtherServer {

	/**
	 * 在線數
	 * <p>
	 * 多線程環境下,為了保證線程安全
	 * </p>
	 */
	private static AtomicInteger online = new AtomicInteger(0);

	/**
	 * 在線客戶端連接集合
	 * <p>
	 * 多線程環境下,為了保證線程安全
	 * </p>
	 */
	private static Map<String, Session> onlineMap = new ConcurrentHashMap<>();

	/**
	 * 建立連接
	 * 
	 * @param session 客戶端連接對象
	 */
	@OnOpen
	public void onOpen(Session session) {
		// 在線數加1
		online.incrementAndGet();
		// 存放客戶端連接
		onlineMap.put(session.getId(), session);
		log.info("客戶端連接建立成功,Session ID:{},當前在線數:{}", session.getId(), online.get());
	}

	/**
	 * 接收客戶端消息
	 * 
	 * @param message 客戶端發送的消息內容
	 * @param session 客戶端連接對象
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		log.info("服務端接收消息成功,Session ID:{},消息內容:{}", session.getId(), message);

		// 處理消息,並響應給客戶端
		this.sendMessage(message, session);
	}

	/**
	 * 處理消息,並響應給客戶端
	 * 
	 * @param message 客戶端發送的消息內容
	 * @param session 客戶端連接對象
	 */
	private void sendMessage(String message, Session session) {
		String response = "Server Response ==> " + message;
		for (Map.Entry<String, Session> sessionEntry : onlineMap.entrySet()) {
			Session s = sessionEntry.getValue();
			// 過濾自己
			if (!(session.getId()).equals(s.getId())) {
				log.info("服務端響應消息成功,接收的Session ID:{},響應內容:{}", s.getId(), response);
				s.getAsyncRemote().sendText(response);
			}
		}
	}

	/**
	 * 關閉連接
	 * 
	 * @param session 客戶端連接對象
	 */
	@OnClose
	public void onClose(Session session) {
		// 在線數減1
		online.decrementAndGet();
		// 移除關閉的客戶端連接
		onlineMap.remove(session.getId());
		log.info("客戶端連接關閉成功,Session ID:{},當前在線數:{}", session.getId(), online.get());
	}

	/**
	 * 連接異常
	 * 
	 * @param session 客戶端連接對象
	 * @param error   異常
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("連接異常:{}", error);
	}

}
  • 創建測試頁面
      在resource下的views文件夾創建測試頁面selfToOtherClient.html:
<!DOCTYPE HTML>
<html>
<head>
	<title>WebSocket - Self To Other</title>
</head>
<body>
	<input id="message" type="text" />
    <button onclick="sendMessage()">發送</button>
    <button onclick="closeWebSocket()">關閉</button>
    <hr/>
    <div id="response"></div>
</body>
<script type="text/javascript">
	var websocket = null;
	
	// 判斷當前瀏覽器是否支持WebSocket
	if ('WebSocket' in window) {
	    websocket = new WebSocket("ws://localhost:8080/selfToOther");
	} else {
	    alert("當前瀏覽器不支持WebSocket");
	}
	
	// 建立連接成功時的回調方法
    websocket.onopen = function (event) {
    	printMessage("green", "建立連接成功!!!");
    }
	
	// 連接異常時的回調方法
    websocket.onerror = function (event) {
    	printMessage("red", "連接異常!!!");
    };

    // 客戶端接收消息時的回調方法
    websocket.onmessage = function (event) {
    	printMessage("blue", event.data);
    }

    // 關閉連接時的回調方法
    websocket.onclose = function() {
    	printMessage("yellow", "關閉連接成功!!!");
    }

    // 監聽窗口關閉事件,當窗口關閉時,主動關閉連接,防止連接未斷開時關閉窗口,服務端拋出異常
    window.onbeforeunload = function() {
        websocket.close();
    }
    
    // 發送消息
    function sendMessage() {
    	if (websocket.readyState != 1) {
    		printMessage("red", "未建立連接或者連接已處於關閉狀態!");
    	} else {
    		 var message = document.getElementById('message').value;
    	     websocket.send(message);
    	}
    }
    
 	// 關閉連接
    function closeWebSocket() {
        websocket.close();
    }
 	
  	// 打印消息
    function printMessage(color, text) {
        document.getElementById("response").innerHTML += "<font color='" + color +"'>" + text + "</font><br/>";
    }
</script>
</html>
  • 添加跳轉頁面方法
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 頁面視圖Controller
 * 
 * @author CL
 *
 */
@Controller
public class ViewController {

	/**
	 * 跳轉到<b> 自己給自己發送消息 </b>頁面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/selfToSelf")
	public String selfToSelf() {
		return "selfToSelfClient";
	}
	
	/**
	 * 跳轉到<b> 自己給其他用戶發送消息 </b>頁面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/selfToOther")
	public String selfToOther() {
		return "selfToOtherClient";
	}

}
  • 測試
    2020-12-29 19:53:52.654  INFO 6420 --- [nio-8080-exec-2] com.c3stones.server.SelfToOtherServer    : 客戶端連接建立成功,Session ID:0,當前在線數:1
    2020-12-29 19:54:01.044  INFO 6420 --- [nio-8080-exec-5] com.c3stones.server.SelfToOtherServer    : 客戶端連接建立成功,Session ID:1,當前在線數:2
    2020-12-29 19:54:14.494  INFO 6420 --- [nio-8080-exec-8] com.c3stones.server.SelfToOtherServer    : 客戶端連接建立成功,Session ID:2,當前在線數:3
    2020-12-29 19:54:27.705  INFO 6420 --- [nio-8080-exec-9] com.c3stones.server.SelfToOtherServer    : 服務端接收消息成功,Session ID:0,消息內容:測試1
    2020-12-29 19:54:27.705  INFO 6420 --- [nio-8080-exec-9] com.c3stones.server.SelfToOtherServer    : 服務端響應消息成功,接收的Session ID:1,響應內容:Server Response ==> 測試1
    2020-12-29 19:54:27.753  INFO 6420 --- [nio-8080-exec-9] com.c3stones.server.SelfToOtherServer    : 服務端響應消息成功,接收的Session ID:2,響應內容:Server Response ==> 測試1
    2020-12-29 19:54:43.084  INFO 6420 --- [nio-8080-exec-2] com.c3stones.server.SelfToOtherServer    : 服務端接收消息成功,Session ID:1,消息內容:測試2
    2020-12-29 19:54:43.085  INFO 6420 --- [nio-8080-exec-2] com.c3stones.server.SelfToOtherServer    : 服務端響應消息成功,接收的Session ID:0,響應內容:Server Response ==> 測試2
    2020-12-29 19:54:43.086  INFO 6420 --- [nio-8080-exec-2] com.c3stones.server.SelfToOtherServer    : 服務端響應消息成功,接收的Session ID:2,響應內容:Server Response ==> 測試2
    2020-12-29 19:54:48.474  INFO 6420 --- [nio-8080-exec-5] com.c3stones.server.SelfToOtherServer    : 服務端接收消息成功,Session ID:2,消息內容:測試3
    2020-12-29 19:54:48.474  INFO 6420 --- [nio-8080-exec-5] com.c3stones.server.SelfToOtherServer    : 服務端響應消息成功,接收的Session ID:0,響應內容:Server Response ==> 測試3
    2020-12-29 19:54:48.475  INFO 6420 --- [nio-8080-exec-5] com.c3stones.server.SelfToOtherServer    : 服務端響應消息成功,接收的Session ID:1,響應內容:Server Response ==> 測試3
    
    • 瀏覽器截圖


3.3 自己給指定用戶發送消息
  • 創建服務端點
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

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.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * <b style="color: blue"> 自己給指定用戶發送消息 </b>
 * 
 * @author CL
 *
 */
@Slf4j
@Component
@ServerEndpoint(value = "/selfToSpecific")
public class SelfToSpecificServer {

	/**
	 * 在線數
	 * <p>
	 * 多線程環境下,為了保證線程安全
	 * </p>
	 */
	private static AtomicInteger online = new AtomicInteger(0);

	/**
	 * 在線客戶端連接集合
	 * <p>
	 * 多線程環境下,為了保證線程安全
	 * </p>
	 */
	private static Map<String, Session> onlineMap = new ConcurrentHashMap<>();

	/**
	 * 建立連接
	 * 
	 * @param session 客戶端連接對象
	 */
	@OnOpen
	public void onOpen(Session session) {
		// 在線數加1
		online.incrementAndGet();
		// 存放客戶端連接
		onlineMap.put(session.getId(), session);
		log.info("客戶端連接建立成功,Session ID:{},當前在線數:{}", session.getId(), online.get());
	}

	/**
	 * 接收客戶端消息
	 * 
	 * @param message 客戶端發送的消息內容
	 * @param session 客戶端連接對象
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		log.info("服務端接收消息成功,Session ID:{},消息內容:{}", session.getId(), message);

		// 解析出指定用戶
		JSONObject jsonObj = JSONUtil.parseObj(message);
		if (jsonObj != null) {
			Session s = onlineMap.get(jsonObj.get("sessionId"));
			// 處理消息,並響應給客戶端
			this.sendMessage(jsonObj.get("message").toString(), s);
		}
	}

	/**
	 * 處理消息,並響應給客戶端
	 * 
	 * @param message 客戶端發送的消息內容
	 * @param session 客戶端連接對象
	 */
	private void sendMessage(String message, Session session) {
		try {
			String response = "Server Response ==> " + message;
			session.getBasicRemote().sendText(response);

			log.info("服務端響應消息成功,接收的Session ID:{},響應內容:{}", session.getId(), response);
		} catch (IOException e) {
			log.error("服務端響應消息異常:{}", e.getMessage());
		}
	}

	/**
	 * 關閉連接
	 * 
	 * @param session 客戶端連接對象
	 */
	@OnClose
	public void onClose(Session session) {
		// 在線數減1
		online.decrementAndGet();
		// 移除關閉的客戶端連接
		onlineMap.remove(session.getId());
		log.info("客戶端連接關閉成功,Session ID:{},當前在線數:{}", session.getId(), online.get());
	}

	/**
	 * 連接異常
	 * 
	 * @param session 客戶端連接對象
	 * @param error   異常
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("連接異常:{}", error);
	}

}
  • 創建測試頁面
      在resource下的views文件夾創建測試頁面selfToSpecificClient.html:
<!DOCTYPE HTML>
<html>
<head>
	<title>WebSocket - Self To Specific</title>
</head>
<body>
	消息:<input id="message" type="text" /><br/>
	Session Id:<input id="sessionId" type="text" /><br/>
    <button onclick="sendMessage()">發送</button>
    <button onclick="closeWebSocket()">關閉</button>
    <hr/>
    <div id="response"></div>
</body>
<script type="text/javascript">
	var websocket = null;
	
	// 判斷當前瀏覽器是否支持WebSocket
	if ('WebSocket' in window) {
	    websocket = new WebSocket("ws://localhost:8080/selfToSpecific");
	} else {
	    alert("當前瀏覽器不支持WebSocket");
	}
	
	// 建立連接成功時的回調方法
    websocket.onopen = function (event) {
    	printMessage("green", "建立連接成功!!!");
    }
	
	// 連接異常時的回調方法
    websocket.onerror = function (event) {
    	printMessage("red", "連接異常!!!");
    };

    // 客戶端接收消息時的回調方法
    websocket.onmessage = function (event) {
    	printMessage("blue", event.data);
    }

    // 關閉連接時的回調方法
    websocket.onclose = function() {
    	printMessage("yellow", "關閉連接成功!!!");
    }

    // 監聽窗口關閉事件,當窗口關閉時,主動關閉連接,防止連接未斷開時關閉窗口,服務端拋出異常
    window.onbeforeunload = function() {
        websocket.close();
    }
    
    // 發送消息
    function sendMessage() {
    	if (websocket.readyState != 1) {
    		printMessage("red", "未建立連接或者連接已處於關閉狀態!");
    	} else {
    		 var message = document.getElementById('message').value;
    		 var sessionId = document.getElementById('sessionId').value;
    		 
    		 var obj = new Object();
    		 obj.message = message;
    		 obj.sessionId = sessionId;
    	     websocket.send(JSON.stringify(obj));
    	}
    }
    
 	// 關閉連接
    function closeWebSocket() {
        websocket.close();
    }
 	
  	// 打印消息
    function printMessage(color, text) {
        document.getElementById("response").innerHTML += "<font color='" + color +"'>" + text + "</font><br/>";
    }
</script>
</html>
  • 添加跳轉頁面方法
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 頁面視圖Controller
 * 
 * @author CL
 *
 */
@Controller
public class ViewController {

	/**
	 * 跳轉到<b> 自己給自己發送消息 </b>頁面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/selfToSelf")
	public String selfToSelf() {
		return "selfToSelfClient";
	}

	/**
	 * 跳轉到<b> 自己給其他用戶發送消息 </b>頁面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/selfToOther")
	public String selfToOther() {
		return "selfToOtherClient";
	}

	/**
	 * 跳轉到<b> 自己給指定用戶發送消息 </b>頁面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/selfToSpecific")
	public String selfToSpecific() {
		return "selfToSpecificClient";
	}

}
  • 測試
    2020-12-29 20:27:47.043  INFO 9004 --- [nio-8080-exec-2] c.c3stones.server.SelfToSpecificServer   : 客戶端連接建立成功,Session ID:0,當前在線數:1
    2020-12-29 20:27:49.558  INFO 9004 --- [nio-8080-exec-4] c.c3stones.server.SelfToSpecificServer   : 客戶端連接建立成功,Session ID:1,當前在線數:2
    2020-12-29 20:27:56.886  INFO 9004 --- [nio-8080-exec-7] c.c3stones.server.SelfToSpecificServer   : 服務端接收消息成功,Session ID:0,消息內容:{"message":"測試1","sessionId":"1"}
    2020-12-29 20:28:06.785  INFO 9004 --- [nio-8080-exec-7] c.c3stones.server.SelfToSpecificServer   : 服務端響應消息成功,接收的Session ID:1,響應內容:Server Response ==> 測試1
    2020-12-29 20:28:19.007  INFO 9004 --- [io-8080-exec-10] c.c3stones.server.SelfToSpecificServer   : 服務端接收消息成功,Session ID:1,消息內容:{"message":"測試2","sessionId":"0"}
    2020-12-29 20:28:19.008  INFO 9004 --- [io-8080-exec-10] c.c3stones.server.SelfToSpecificServer   : 服務端響應消息成功,接收的Session ID:0,響應內容:Server Response ==> 測試2
    
    • 瀏覽器截圖

4. 項目地址

  spring-boot-websocket-demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM