1. 程式人生 > >springboot整合websocket & 伺服器主動推送資料到前端

springboot整合websocket & 伺服器主動推送資料到前端

       一般前端請求伺服器介面都是使用主動請求的模式,有ajax等。但分不同使用場景 有不一樣的需求, 比如要求實時性比較高的場景使用ajax則不好實現,且實現了開銷也大。所以有了websocket這種長連結的形式保持在前端與伺服器的通訊協議。

現在很多後端框架都使用springboot,那麼如何在springboot中整合websocket服務呢?直接上程式碼,更加清晰明瞭!

首先 在 pom 中加入 websocket 依賴

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

建立 socketConfig.class 配置類

@Configuration
public class SocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {

        return new ServerEndpointExporter();
    }

}

建立 websocket.class 介面服務類

注意需要宣告為@Component ,這樣springboot才會注入並管理

@Component
@ServerEndpoint(value = "/webSocket")
public class websocket{

    private Session session;
    private static ConcurrentHashMap<String, SocketService> webSocketSet = new ConcurrentHashMap<String, SocketService>(16);

    // 監聽連線
    @OnOpen
    public void onOpen(Session session) throws IOException {
        webSocketSet.put(webSocketSet.size() + "", this);
    }

    // 監聽斷開連線
    @OnClose
    public void onClose() {
        System.out.println("closed");
    }

    // 監聽收到客戶端訊息
    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println(message);
        this.session.getBasicRemote().sendText("return your message :" + message);
    }

    @OnError
    public void onError(Throwable error) {
        System.out.println("error");
    }

    // 傳送訊息
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    // 模擬群發訊息,即服務端統一發送訊息給所有已連線的客戶端
    public static void sendAll(String message) {
        for (String key : webSocketSet.keySet()) {
            try {
                webSocketSet.get(key).sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
}

到此 websocket 的服務端基本功能已經全部寫好,前端直接連線 localhost:8080/webSocket 即可。

其實還有一個問題,比如碰到要在某個方法裡面呼叫推送功能的話該如何是好呢?這裡使用session進行傳送資料,那麼每個客戶端連線成功時,以上的程式碼中已經把 session 存到 websocketSet 堆疊中,筆者已經封裝好一個sendAll 推送方法,當要在別的邏輯中進行推送時可以直接呼叫 sendAll 即可。controller 進行推送的示例如下:


@RestController
@RequestMapping(value = "base")
public class BaseController {
    @RequestMapping(value = "base")
    public void base() {
       SocketService.sendAll("伺服器訊息推送");
    }
}

這裡 請求 localhost:8080/base/base ,伺服器就好對已經連線上的客戶端進行訊息推送啦。