WebSocket是一種網絡通訊協議,熟悉計算機網絡的人都知道,通常咱們採用的http請求,都是請求/響應的模式,即客戶端發起請求,服務端從而對客戶端的請求作出相應的響應,然而服務端通常都不能主動的往客戶端發消息,WebSocket正好解決這一問題,本文采用springboot集成WebSocket;web
(1)在pom.xml中加入依賴:spring
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
複製代碼
(2)建立一個WebSocketConfig類,在其中寫入後端
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
複製代碼
(3)建立一個SocketServer類,在其中寫入:springboot
@ServerEndpoint(value = "/socketServer/{productId}/{mapId}")
@Component
@Slf4j
public class SocketServer {
private static final String ADMIN_USER = "server-admin";
private Session session;
private static Map<String,Session> sessionPool = new HashMap<String,Session>();
private static Map<String,String> sessionIds = new HashMap<String,String>();
private MonitorService monitorService;
private DeviceService deviceService;
private String handshake;
private String getMapId;
public static String productCopyId;
public static String mapCopyId;
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext context){
applicationContext = context;
}
/**
* 用戶鏈接時觸發
* @param productId productId
* @param mapId mapId
* @param session session
*/
@OnOpen
public void open(Session session, @PathParam(value="productId")String productId, @PathParam(value="mapId")String mapId)throws Exception{
log.info("{{}}握手成功{{}}",productId,mapId);
this.session = session;
handshake = productId;
getMapId = mapId;
productCopyId = productId;
mapCopyId = mapId;
sessionPool.put(productId, session);
sessionIds.put(session.getId(), productId);
sendMessage(handshake,handshake);
}
/**
* 收到信息時觸發
* @param message message
*/
@OnMessage
public void onMessage(String message){
log.info("發送人:"+sessionIds.get(session.getId())+"內容:"+message);
}
/**
* 鏈接關閉觸發
*/
@OnClose
public void onClose(){
sessionPool.remove(sessionIds.get(session.getId()));
sessionIds.remove(session.getId());
}
/**
* 發生錯誤時觸發
* @param session session
* @param error error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
*信息發送的方法
* @param message message
* @param clientId clientId
*/
public synchronized static void sendMessage(String message,String clientId) throws Exception{
log.info("sendMessage方法被調用");
Session s = sessionPool.get(clientId);
if(s!=null){
try {
log.info("{{}}sendMessage發送的消息爲{{}}",clientId ,message);
s.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 獲取當前鏈接數
* @return int
*/
public synchronized static int getOnlineNum(){
if(sessionIds.values().contains(ADMIN_USER)) {
return sessionPool.size()-1;
}
return sessionPool.size();
}
/**
* 獲取在線用戶名以逗號隔開
* @return String
*/
public synchronized static String getOnlineUsers(){
StringBuffer clientIds = new StringBuffer();
for (String key : sessionIds.keySet()) {
if (!ADMIN_USER.equals(sessionIds.get(key)))
{
clientIds.append(sessionIds.get(key)+",");
}
}
return clientIds.toString();
}
/**
* 信息羣發
* @param msg
*/
public synchronized static void sendAll(String msg) throws Exception{
for (String key : sessionIds.keySet()) {
if (!ADMIN_USER.equals(sessionIds.get(key)))
{
sendMessage(msg, sessionIds.get(key));
}
}
}
/**
* 多我的發送給指定的幾個用戶
* @param msg
* @param clientIds 用戶
*/
public synchronized static void SendMany(String msg,String [] clientIds) throws Exception{
log.info("SendMany方法被調用");
for (String clientId : clientIds) {
sendMessage(msg, clientId);
}
}
}
複製代碼
至此,後端的工做基本完成了;websocket
推廣一下,若是在springboot中的SocketServer類想要加載Service類,它是加載不到的,因此須要在該類中加入如下代碼:網絡
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext context){
applicationContext = context;
}
複製代碼
用以加載springboot中的Bean類;session
而後用如下代碼加載該Beanapp
deviceService = applicationContext.getBean(DeviceService.class);
複製代碼
最後,須要在啓動類中加入如下代碼,才能加載到Beansocket
ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
複製代碼
其中DemoApplication爲啓動類的類名,至此就能夠了;(備註:若是本文侵權,請聯繫做者刪除)spring-boot