首页 > 技术文章 > 个人网站新功能:聊天室

xiepl1997 2021-03-05 13:33 原文

之前在个人网站上预留了一个网页聊天室的功能,在这次寒假抽出了时间来完成。快速访问

简要记录一下网页聊天室的设计过程。

AJAX轮询

在设计之前一直纠结该使用何种方式来实现网页聊天室这个模块,最基本的想法是使用ajax来实现轮询,从而达到消息推送的目的,目前的很多网站也是通过这样的手段来实现推送技术。轮询是在特定的时间间隔(如每一秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这样传统的模式需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

WebSocket

HTML5定义的WebSocket协议,能够更好地节省服务器资源和带宽,并且能够更实时地进行通讯。

WebSocket是为了解决实时传送消息的问题,当然也可以传送数据,但是不保证传送的效率和质量,而WebRTC可用于可靠地传输音视频数据、文件等。并且可以建立P2P连接,不需要服务进行转发数据。虚拟电话、在线面试等现在很多都采用WebRTC来实现。

WebSocket并不是我们寻常意义上的基于TCP或者UDP协议的套接字,而是一个基于TCP的应用层协议,和HTTP协议工作在计算机网络的同一层;WebSocket其实就是,在TCP的基础上增加了一个协议,这个协议和TCP协议很想,也需要握手,挥手,发送大数据也要分包,也是按照位进行标识,但它并不是套接字,不是socket,socket工作在传输层,它工作在应用层。

浏览器通过JavaScript想服务器发出建立WebSocket连接的请求,连接建立后,客户端和服务器端就可以通过TCP连接直接交换数据。当获取到Web Socket连接后,可以通过send()方法来向服务器发送数据,并通过onmessage时间来接受服务器返回的数据。

JS代码如下:

<script type="text/javascript">
    var socket;
    if (!window.WebSocket) {
        window.WebSocket = window.MozWebSocket;
    }
    if (window.WebSocket) {
        socket = new WebSocket("ws://www.xpllyn.com:3333");
        socket.onopen = function () {
            var param = {
                id: $('.user').attr('name'),
                type: 'REGISTER'
            };
            socket.send(JSON.stringify(param));
        };
        socket.onmessage = function (event) {
            var json = JSON.parse(event.data);
            if (json.status == 200) {
                var type = json.data.type;
                switch (type) {
                    case "SINGLE_SENDING":
                        ws.singleReceive(json.data);
                        break;
                    case "GROUP_SENDING":
                        ws.groupReceive(json.data);
                        break;
                    case "GROUP_SENDING_All":
                        ws.groupReceiveAll(json.data);
                        break;
                    case "AGREE_FRIEND_REQUEST":
                        addPerson(json.data);
                        break;
                    default:
                        break;
                }
            }
        };
        socket.onclose = function (event) {
            socket.close();
            alert('连接已断开!');
            window.location.replace('http://www.xpllyn.com/loginpage');
        };
        socket.onerror = function (event) {
            socket.close();
            alert('发生错误!');
            window.location.replace('http://www.xpllyn.com/loginpage');
        };
    } else {
        alert("您的浏览器不支持WebSocket!");
    }
</script>

浏览器端可以通过JavaScript来使用WebSocket实现消息的发送和接收,那么服务器端该如何处理消息发送和接收呢?

推荐阅读