• WebSocket入门


    HTML5 拥有众多引人注目的新特性,如 Canvas、本地存储、多媒体编程接口、WebSocket 等等。其中,WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。使用 WebSocket,web开发人员可以很方便地构建实时 web 应用。

    本文首先介绍WebSocket的基本知识,然后介绍两个常用的WebSocket库——socket.ioSockJS-tornado

    背景

    以前,很多网站使用轮询实现推送技术。轮询是在特定的的时间间隔(比如1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给浏览器。轮询的缺点很明显,浏览器需要不断的向服务器发出请求,然而HTTP请求的header是非常长的,而实际传输的数据可能很小,这就造成了带宽和服务器资源的浪费。

    Comet使用了AJAX改进了轮询,可以实现双向通信。但是Comet依然需要发出请求,而且在Comet中,普遍采用了长链接,这也会大量消耗服务器带宽和资源。

    于是,WebSocket协议应运而生。

    WebSocket协议

    浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器通过 TCP 连接直接交换数据。WebSocket 连接本质上是一个 TCP 连接。

    WebSocket在数据传输的稳定性和数据传输量的大小方面,具有很大的性能优势。Websocket.org 比较了轮询和WebSocket的性能优势:

    websocket vs polling

    从上图可以看出,WebSocket具有很大的性能优势,流量和负载增大的情况下,优势更加明显。

    例子

    浏览器请求

    GET / HTTP/1.1
    Upgrade: websocket
    Connection: Upgrade
    Host: example.com
    Origin: null
    Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
    Sec-WebSocket-Version: 13
    

    服务器回应

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
    Sec-WebSocket-Origin: null
    Sec-WebSocket-Location: ws://example.com/
    

    在请求中的Sec-WebSocket-Key是随机的,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把Sec-WebSocket-Key加上一个魔幻字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11。使用 SHA-1 加密,之后进行 BASE-64编码,将结果作为 Sec-WebSocket-Accept 头的值,返回给客户端。

    浏览器兼容性

    最新的主流浏览器对WebSocket支持良好:

    • Chrome 4+
    • Firefox 4+
    • Internet Explorer 10+
    • Opera 10+
    • Safari 5+

    Socket.IO

    Socket.IO是一个封装了WebSocket的JavaScript模块。因为完全使用JavaScript编写,所以在每个浏览器和移动设备中都可以方便地通过Socket.IO使用WebSocket。

    服务器端

    var io = require('socket.io').listen(80);
    
    io.sockets.on('connection', function (socket) {
      socket.emit('news', { hello: 'world' });
      socket.on('my other event', function (data) {
        console.log(data);
      });
    });
    

    客户端

    
    
    

    SockJS-tornado

    SockJS-tornado是一个配合Tornado框架使用的Python模块。

    from tornado import web, ioloop
    from sockjs.tornado import SockJSRouter, SockJSConnection
    
    class EchoConnection(SockJSConnection):
        def on_message(self, msg):
            self.send(msg)
    
    if __name__ == '__main__':
        EchoRouter = SockJSRouter(EchoConnection, '/echo')
    
        app = web.Application(EchoRouter.urls)
        app.listen(9999)
        ioloop.IOLoop.instance().start()
    

    编撰 SegmentFault

  • 相关阅读:
    不容易系列之一(错排)
    找新朋友(欧拉函数)
    二分查找
    快速排序(分治)
    归并排序(分治)
    畅通工程(并查集)
    A Knight's Journey (DFS)
    Network Saboteur (DFS)
    Oil Deposits(油田)(DFS)
    Dungeon Master (三维BFS)
  • 原文地址:https://www.cnblogs.com/10manongit/p/12989143.html
Copyright © 2020-2023  润新知