基於WebSocket實現網頁版聊天室

  WebSocket ,HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議,其使用簡單,應用場景也普遍,不一樣開發語言都用種類繁多的實現,僅Java體系中,Tomcat,Jetty,Spring等都提供了對WS的API支持。本篇不作理論探究,僅自娛自樂,簡單實現網頁版的聊天室功能,在實際開發場景中變通使用便可。廢話不嘰歪,直接擼出來——html

1  簡單頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HanppyRoom</title>
    <script>
        var url = "ws://" + window.location.host + "/page_room/";
        var ws = null;
        //加入聊天室
        function joinRoom() {
            if (ws) {
                alert("你已經在聊天室,不能再加入");
                return;
            }
            var username = document.getElementById("user").value;
            ws = new WebSocket(url + username);
            //與服務端創建鏈接觸發
            ws.onopen = function () {
              console.log("與服務器成功創建鏈接")
            };
            //服務端推送消息觸發
            ws.onmessage = function (ev) {
                talking(ev.data);
            };

            //發生錯誤觸發
            ws.onerror = function () {
                console.log("鏈接錯誤")
            };
            //正常關閉觸發
            ws.onclose = function () {
                console.log("鏈接關閉");
            };
        }

        //退出聊天室
        function exitRoom() {
            closeWebSocket();
        }

        function sendMsg() {
            if(!ws){
                alert("你已掉線,請從新加入");
                return;
            }
            //消息發送
            ws.send(document.getElementById("sendMsg").value);
            document.getElementById("sendMsg").value = "";


        }

        function closeWebSocket() {
            if(ws){
                ws.close();
                ws = null;
            }
        }

        function talking(content) {
            document.getElementById("content").append(content + "\r\n");
        }
    </script>
</head>
<body>
<div style="text-align: center;background-color: rgba(129,86,255,0.35);margin:0 auto;border:1px solid #000;width:600px;height:650px">
    <br>歡迎使用<strong>陳本布衣</strong>牌極簡聊天室:<br/><br/>
    <textarea id="content" cols="60" rows="30" readonly="readonly"></textarea><br>
    <input type="text" id="sendMsg">
    <button type="button" onclick="sendMsg()">發送消息</button>
    <br/><br/>
    用戶:<input type="text" id="user">
    <button onclick="joinRoom()">加入羣聊</button>
    <button onclick="exitRoom()">退出羣聊</button>
</div>
</body>
</html>

2   後端實現

/**
 * @ServerEndpoin 註解聲明該類爲 WebSocket 的服務端端點
 * value 值爲監聽客戶端訪問的 URL
 */
@ServerEndpoint(value = "/page_room/{username}")
public class WsByTomcat {

    //這裏只是簡單測試用,真正的場景請考慮線程安全的容器或其它併發解決方案
    private static List<Session> sessions = new ArrayList<>();

    /**
     * @param session  與客戶端的會話對象【可選】
     * @param username 路徑參數值 【可選】
     * @throws IOException
     * @OnOpen 標註此方法在 ws 鏈接創建時調用,可用來處理一些準備性工做 可選參數
     * EndpointConfig(端點配置信息對象) Session 鏈接會話對象
     */
    @OnOpen
    public void OnOpen(Session session, @PathParam("username") String username) throws IOException {
        sessions.add(session);
        sendTextMsg("好友 [" + username + "] 加入羣聊");
    }

    /**
     * @param msg      接受客戶端消息
     * @param username RESTful 路徑方式獲取用戶名
     * @throws IOException
     * @OnMessage 在收到客戶端消息調用 消息形式不限於文本消息,還能夠是二進制消息(byte[]/ByteBuffer等),ping/pong 消息
     */
    @OnMessage
    public void OnMsg(String msg, @PathParam("username") String username) throws IOException {
        sendTextMsg(username + ":\r\n" + msg);
    }


    /**
     * @OnClose 鏈接關閉調用
     */
    @OnClose
    public void OnClose(Session session, @PathParam("username") String username) throws IOException {
        sessions.remove(session);
        sendTextMsg("好友 ["+username + "] 退出羣聊");
    }

    /**
     * @param e 異常參數
     * @OnError 鏈接出現錯誤調用
     */
    @OnError
    public void OnError(Throwable e) {
        e.printStackTrace();
    }

    private void sendTextMsg(String msg) {
        for (Session session : sessions) {
            session.getAsyncRemote().sendText(msg);
        }
    }
}

3   3P聊天效果

相關文章
相關標籤/搜索