websocket的簡單使用

項目中碰到從後臺實時接收通知然後語音播放的需求,以前項目中調用過別人寫的websocket接口,這次自己寫了一下,分享下:

1.依賴的引入

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-websocket</artifactId>

<version>1.5.3.RELEASE</version>

<type>pom</type>

</dependency>

以上是springboot工程的引入,如果是普通的war包部署tomcat可以如下配置:

<dependency>

<groupId>javax</groupId>

<artifactId>javaee-api</artifactId>

<version>7.0</version>

<scope>provided</scope>

</dependency>

2.聲明註冊使用@ServerEndpoint 註解,

@Configuration

public class WebSocketConfig {

@Bean

public ServerEndpointExporter serverEndpointExporter(){

return new ServerEndpointExporter();

} }

3.寫服務類

@ServerEndpoint(value = "/websocket") //接受websocket請求路徑
@Component  //註冊到spring容器中
public class AlarmWebSocket {
    //保存所有在線socket連接
    private static Map<String,AlarmWebSocket> webSocketMap = new LinkedHashMap<>();

    //記錄當前在線數目
    private static int count=0;

    //當前連接(每個websocket連入都會創建一個MyWebSocket實例
    private Session session;

    private Logger log = LoggerFactory.getLogger(this.getClass());
    //處理連接建立
    @OnOpen
    public void onOpen(Session session){
        this.session=session;
        webSocketMap.put(session.getId(),this);
        addCount();
        log.info("新的連接加入:{}",session.getId());
    }

    //接受消息
    @OnMessage
    public void onMessage(String message,Session session){
        log.info("收到客戶端{}消息:{}",session.getId(),message);
        try{
            this.sendMessage("收到消息:"+message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //處理錯誤
    @OnError
    public void onError(Throwable error,Session session){
        log.info("發生錯誤{},{}",session.getId(),error.getMessage());
    }

    //處理連接關閉
    @OnClose
    public void onClose(){
        webSocketMap.remove(this.session.getId());
        reduceCount();
        log.info("連接關閉:{}",this.session.getId());
    }

    //羣發消息

    //發送出去消息
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);//這裏可以寫死字符串測試
    }

    //廣播消息
    public static void broadcast(String message){
        AlarmWebSocket.webSocketMap.forEach((k,v)->{
            try{
                v.sendMessage(message);
            }catch (Exception e){
            }
        });
    }

    //獲取在線連接數目
    public static int getCount(){
        return count;
    }

    //操作count,使用synchronized確保線程安全
    public static synchronized void addCount(){
        AlarmWebSocket.count++;
    }

    public static synchronized void reduceCount(){
        AlarmWebSocket.count--;
    }
}

4.前端建立連接及發送消息測試

<html>

<head> <title>websocket測試</title> <meta charset="utf-8" /> </head>

<body>

<button οnclick="sendMessage()">測試</button>

<script>

let socket = new WebSocket("ws://localhost:8080/websocket");

socket.onerror = err => { console.log(err); };

socket.onopen = event => { console.log(event); };

socket.onmessage = mess => { console.log(mess); };

socket.onclose = () => { console.log("連接關閉"); };

function sendMessage() {

if (socket.readyState === 1) socket.send("這是向後臺發送的測試數據");

else alert("還沒成功建立websocket連接"); }

</script> </body> </html>

5.如果前臺沒問題,後臺測試發送給前臺消息

@RestController

public class TestController {

@GetMapping("/broadcast")

public void broadcast(){ MyWebSocket.broadcast();

} }

在瀏覽器F12打開前端日誌,觀察websocket狀態,打印:

Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}

type狀態是open表示成功建立websocket連接,後臺發送給前端消息,也可以打印出日誌

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章