websocket實時聊天(一)


 今天簡單看了一下webscoket的相關內容,寫了一個入門demo,簡單記錄一下。

1、服務端

  服務端使用springboot來搭建,引入spring-boot-starter-websocket模塊,以及web模塊來做頁面。頁面使用簡單的thymeleaf模板。

  • 配置websocket

服務的配置websocket需要先定義WebSocketExporter的bean,使用默認的構造方法即可。

package com.chat.config;

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();
    }
}
  • 創建websocket服務

創建websocket服務主要需要處理創建連接、發送消息、斷開連接、發生錯誤這幾種情況的邏輯。

package com.chat.bean;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

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;

@ServerEndpoint(value="/sunSocket")
@Component
public class SunWebSocket {

    /**
     * 記錄在線鏈接數
     */
    private static int onLineNum = 0;
    
    /**
     * concurrent包的線程安全set,存放每個客戶端連接對應的webSocket對象。
     */
    private static CopyOnWriteArraySet<SunWebSocket> webSocketSet = new CopyOnWriteArraySet<>();

    
    /**
     * 與某個客戶端的會話,通過會話給客戶端傳遞消息
     */
    private Session session;
    
    /**
     * 開啟一個客戶端對話連接
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);
        addOnlineCount();
        sendMsg("歡迎加入聊天室", session);
    }
    
    /**
     * 當連接斷開時調用的方法
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        webSocketSet.remove(this);
        subOnlineCount();
        System.out.println("有人走了");
    }
    
    /**
     * 當有來自客戶端的消息時
     * @param msg
     * @param session
     */
    @OnMessage
    public void onMessage(String msg,Session session) {
        Map<String, String> map = new HashMap<>();
        map.put("ip",session.getId());
        map.put("msg",msg);
        for (SunWebSocket sunWebSocket : webSocketSet) {
            try {
                sunWebSocket.session.getBasicRemote().sendText(session.getId() + ":" + msg);
            } catch (IOException e) {
                e.printStackTrace();
            } 
        }
    }
    
    @OnError
    public void onError(Session session,Throwable error) {
        
        try {
            session.getBasicRemote().sendText(error.getMessage());
        } catch (IOException e) {
            error.printStackTrace();
            e.printStackTrace();
        }
    }
    
    public void sendMsg(String msg, Session session) {
        
        try {
            session.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static synchronized int getOnlineCount() {
        return onLineNum;
    }

    public static synchronized void addOnlineCount() {
        onLineNum++;
    }

    public static synchronized void subOnlineCount() {
        onLineNum--;
    }
}

啟動springboot服務后台內容即完成。

2、客戶端

demo的客戶端使用html5的websocket來編寫。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>在線聊天</title>
<style type="text/css">
#msg-view{
    
    height: 400px;
    overflow: scroll;
}
</style>
</head>
<body>
    <div id="msg-view">
    
    </div>
    <div id="msg-input">
        <input id="msg"/>
        <button id="sendBtn" onclick="sendMsg()">發送</button>
    </div>
    <script type="text/javascript">
        
    var websocket = null;
    if('WebSocket' in window){
        websocket = new WebSocket("ws://localhost:8080/sunSocket")
    }
    else{
        alert('Not support websocket')
    }
    
    websocket.onmessage = function (event) {
        
        var data = event.data;
        if(typeof(data) == 'string'){
            showMsg(data)
        }else{
            showMsg(data.ip + ':' + data.msg)
        }
    }
    /* 頁面關閉監聽 */
    window.onbeforeunload = function(){
        websocket.close();
    }
    /**
     *    錯誤情況
     */
    websocket.onerror = function () {
        showMsg('連接異常')
    }
    
    
    function sendMsg() {
        var msg = document.getElementById('msg').value;
        websocket.send(msg)
    }
    
    function showMsg(msg) {
        document.getElementById('msg-view').innerHTML += msg + '<br/>';
    }
    </script>
</body>
</html>

 


免責聲明!

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



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