websocket

作者: 彩色系 | 来源:发表于2017-09-26 12:55 被阅读70次

    websocekt 协议

    试想,如果要是想实现一个全站通知的功能,管理员在网站输入一个通知消息,服务器接收
    到这个管理员发送的消息,将这个消息来广播出去。
    传统的实现方式是什么呢?
    由于在http中 一个request 对应一个 response ,这个response是被动的。

    ajax轮训, 或者 long poll
    ajax轮训是客户端每隔一段时间就向服务器发送一个请求,查看是否有新的通知消息。
    是一种同步非阻塞的模型。

    还有一种方式是long poll,如果没有就一直等待,是一种阻塞的模型。

    这两种方式都是被动的从服务端来获取消息。这样会浪费很多的资源。

    而websocket 能够进行主动推送信息。经过一次http握手就可以进行。当服务端有信息
    时可以直接进行推送。

     HTTP/1.1 101 Switching Protocols
     Upgrade: websocket
     Connection: Upgrade
     Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
     Sec-WebSocket-Protocol: chat
    
     Upgrade: websocket
     Connection: Upgrade
    

    可以看到 这里首先来选择协议,经过http握手后变为了websocket。
    此时在浏览器中的抓包已经看不到websocket 的协议的内容了。

    一个简单的demo

    web服务

    from flask import Flask, render_template
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return render_template('socket.html')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    socketio服务

    from aiohttp import web
    
    import socketio
    
    sio = socketio.AsyncServer(async_mode='aiohttp')
    app = web.Application()
    sio.attach(app)
    
    @sio.on('my broadcast event', namespace='/test')
    async def test_broadcast_message(sid, message):
        await sio.emit('my response', {'data':  message['data']}, namespace='/test')
    
    
    if __name__ == '__main__':
        web.run_app(app, host='localhost', port=8000)
    

    上面使用了asyncio 的异步模式,可以进行大规模的链接。

    socket.html
    主要如下:
    引入socketio 包,这个包可以在不支持websocket的浏览器上切换成其他方式

    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
    

    实例化

    var socket = io.connect('http://' + document.domain + ':' + port+ namespace);
    

    接收消息
    socket.on
    发送消息
    socket.emit

    博客 https://www.97up.cn/

    相关文章

      网友评论

        本文标题:websocket

        本文链接:https://www.haomeiwen.com/subject/bkgusxtx.html