通過springBoot集成搭建webScoket伺服器

前言:

  最近工作中有一個需求,就是服務端要主動推送消息給客戶端,而我們平常的Http請求只能一請求一響應,為此學習了webScokset通訊技術,以下介紹的是java 通過SpringBoot集成webScoket搭建服務端。


1.引入webScoket依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>

2.bean注入

  • ServerEndpointExporter 這個Bean會自動註冊使用@ServerEndpoint註解聲明的websocket endpoint

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

3.創建scoket的Server服務

  創建一個java類 WebScoketServer,以下為我自己寫的一個小demo,實現的就是服務端和客戶端一個對話(客戶端沒有搭建用的網頁測試),效果我會在下面測試演示。
  其他具體業務邏輯在連接成功或者收到資訊後方法里進行處理

@ServerEndpoint("/webSocket/{username}")
@Component
@Slf4j
public class WebScoketServer {

    //concurrent包的執行緒安全Set,用來存放每個客戶端對應的WebSocketServer對象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    private static Map<Session, List<String>> map =new HashMap<>();

    //發送消息
    public void sendMessage(Session session, String message) throws IOException {
            synchronized (session) {
                System.out.println("發送數據:" + message);
                session.getBasicRemote().sendText(message);
            }

    }


    //建立連接成功調用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "username") String userName){
        log.info("連接建立 userName是{}",userName);
        sessionPools.put(userName,session);
        List<String> list =new ArrayList<>();
        list.add("服務端--》哈哈哈建立連接後的回復         ");
        map.put(session,list);
        try {
            sendMessage(session,list.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("連接建立");
    }

    //關閉連接時調用
    @OnClose
    public void onClose(@PathParam(value = "username") String userName){
        log.info("連接關閉 userName是{}",userName);
        System.out.println("連接關閉");
    }

    //收到客戶端資訊後
    @OnMessage
    public void onMessage(String message,@PathParam(value = "username") String userName) throws IOException{
        log.info("收到消息 message是{}",message);
        try {
            Session session = sessionPools.get(userName);
            List<String> list = map.get(session);
            list.add("客戶端--》"+message+"                        ");
            list.add("服務端--》我收到消息:"+message+"                        ");
            map.put(session,list);


            sendMessage(session,list.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("收到消息");
    }

    //錯誤時調用
    @OnError
    public void onError(Session session, Throwable throwable){
        log.info("連接錯誤");
        System.out.println("連接錯誤");
    }
}

4.測試

image