WebSocket

  • Post author:
  • Post category:其他


ajax轮询

每隔一段时间发送一次请求询问服务器有消息发送不(需要服务器有很快的处理速度)

长轮询

发送一次请求然后一直等待直到服务器有消息发送,服务器发完消息后连接中断,客户端重新建立连接请求,周而复始重复。(需要服务器有很高的并发性,即同时处理)

以上两种都需要重复建立连接,且容易使服务器崩溃。

websocket

是HTML5的新协议,实现了浏览器和服务器的全双工通信,节省带宽实时通信。还是需要通过HTTP请求建立连接

Upgrade:websocket    
Connection:Upgrade  
Sec-WebSocket-Key:gjre9ujg9-ertiuhffuuuh

其中, Sec-Websocket-Key是客户端发送的一个base64编码的密文,要求服务器端返回一个对应加密的应答Sec-WebSocket-Accept。


一个websocket连接是在客户端和服务器端的http协议初始握手阶段升级到websocket协议的,底层还是TCP连接

websocket和http共享端口80和443(安全版本)

利用

nodejs-websocket

实现简单聊天界面

1. npm install nodejs-websocket

2.HTML页面实现消息的发送与显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>chat room</title>
    <style type="text/css">
        #messageArea {
            padding: 10px;
            width: 50%;
            border: thin sienna;
        }

        #messageArea p {
            border-bottom: thin solid gray;
        }
        #connection p {
            border-bottom: thin solid red;
        }
    </style>
</head>
<body>
<h1>chat room</h1>
<input id="text">
<input type="button" id="button" value="send">
<div id="messageArea"></div>
<div id="connection"></div>
<script type="text/javascript">
    var text = document.getElementById('text');
    var mesAre = document.getElementById('messageArea');
    var button = document.getElementById('button');
    var connection = document.getElementById('connection');
    var ws = new WebSocket('ws://localhost:8080');//在8080端口建立websocket连接,注意此处的协议为ws

    ws.onopen = function () {
        console.log('connected!');//连接打开后显示
        button.onclick = function () {
            var sendText = text.value ? text.value : 'empty data';
            ws.send(sendText);//连接打开后并点击按钮时发送input中的消息
        }
    };
    ws.onmessage = function (e) {
        var obj = JSON.parse(e.data);
        showMessage(obj);//接收到消息时显示消息
    };

    ws.onclose = function () {
        console.log('closed');//连接关闭
    };
    function showMessage(obj) {
        console.log(JSON.stringify(obj));
        var p;
        switch (obj.type){
            case 'establish':
                document.title = obj.count+' in';
                p = document.createElement('p');
                p.innerHTML = 'user '+obj.count+' established';
                connection.appendChild(p);
                break;
            case 'context':
                p = document.createElement('p');
                p.innerHTML = 'message from '+ obj.count+' : '+ obj.context;
                mesAre.appendChild(p);
                break;
            case 'close':
                p = document.createElement('p');
                p.innerHTML = 'user '+obj.count+' closed';
                connection.appendChild(p);
                break;
            default:
                break;
        }
    }
</script>
</body>
</html>

服务器端设置

var port = 8080;
var ws = require('nodejs-websocket');
var count = 0;
var server = ws.createServer(function (conn) {//建立websocket服务器
    count++;//每当打开一个连接后,server中的connections属性上就会添加一个新连接
    var detail = {
        count: count,
        type: 'establish'
    };

    conn.seq = count;//每个连接的标识
    broadcast(JSON.stringify(detail));

    console.log('new connection');

    conn.on('text', function (str) {//客户端调用send方法时触发
        var detail = {
            count: this.seq,
            type: 'context',
            context: str
        };
        var textDetail = JSON.stringify(detail);
        broadcast(textDetail);//将客户端发来的消息广播到所有客户端
        console.log('received ' + textDetail);
    });
    conn.on('close', function (code, reason) {
        var detail = {
            count: this.seq,
            type: 'close',
        };
        var textDetail = JSON.stringify(detail);
        broadcast(textDetail);
        console.log('connection closed ' + code + ' ' + reason);
    });
    conn.on('error', function () {
        console.log('error')
    })
}).listen(port);

function broadcast(str) {//广播发送消息
    server.connections.forEach(function (conn) {
        var obj = JSON.parse(str);
        obj.seq = conn.seq;
        console.log(JSON.stringify(obj));
        conn.sendText(JSON.stringify(obj));
    });
}



版权声明:本文为u012657197原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。