flask之gevent-websocket的IO多路复用长连接通信

本节目录:

(一)笔记总结;

(二)gevent-websocket+flask+javascript实现WS即时通信

  (1)无昵称群聊

  (2)有昵称群聊

  (3)私聊

 

三种通信模型简述: 

(1)轮询:
客户端周期性不间断高频率的给服务器发送请求:
客户端请求--服务器响应--断开连接,请求次数QPS比较频繁,对客户端和服务器的配置要求比较高
(2)长轮询:
客户端周期性不间断的给服务器发送请求:
客户端与服务器建立的连接会保持一定时间,因此请求相对不会特别频繁
(3)长连接:
客户端与服务端建立连接后,如果不是特殊原因(客户端主动断开,服务器故障)连接会一直保持
同时通过多线程进行IO多路复用技术解决并发问题

flask中基于gevent-websocket的IO多路复用技术进行长连接通信:  

(1)基于gevent-websocket的IO多路复用长连接通信,需要导入一下模块:
#pip install gevent-websocket导入IO多路复用模块
        from geventwebsocket.handler import WebSocketHandler         #提供WS(websocket)协议处理
        from geventwebsocket.server import WSGIServer                #websocket服务承载
        #WSGIServer导入的就是gevent.pywsgi中的类
        # from gevent.pywsgi import WSGIServer
        from geventwebsocket.websocket import WebSocket              #websocket语法提示
(2)路由视图函数中的处理必须通过request.environ.get('wsgi.websocket')获取与客户端的ws连接client_socket:
 #websocket协议通信如下(http请求正常处理即可)
        @app.route()
        def func():
            client_socket=request.environ.get('wsgi.websocket')
            while 1:
                client_socket.recive()
                    ...
                client_socket.send(str)
                    ...
(3)flask项目启动如下:
WSGIServer默认处理的是http请求,路由视图中可以正常使用http,
但是在使用ws协议时务必在视图函数通过request.environ.get('wsgi.websocket')获取与客户端的ws连接client_socket,
通过连接client_socket进行client_socket.recive()/client_socket.send()通信,这连个方法会对字符串自动进行编解码)
http_server=WSGIServer(('192.168.16.14',8888),application=app,handler_class=WebSocketHandler。
http_server.serve_forever()
(4)前端页面使用js进行WS(websocket)请求:
浏览器提供了websocket客户端,直接new创建websocket连接ws,
(ws状态码0表示已创建未连接,1表示已连接保持中,2表示客户端主动断开连接,3表示服务端断开连接),
通过ws.onmessage=function (MessageEvent){}监听执行回调函数获取信息MessageEvent.data,
通过ws.send()发送信息。
<script>
    var ws = new WebSocket('ws://192.168.16.14:8888/websocket');
    ws.onmessage = function (MessageEvent) {
        console.log(MessageEvent);
        console.log(MessageEvent.data);        
    };

    function send() {
        var msg = document.getElementById('msg').value;
        ws.send(msg);
    }
</script>

http请求协议和websocket请求协议的请求原数据request.environ和请求头部信息request.headers比较:
http-environ:

{
     'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6', 
     'SCRIPT_NAME': '', 'wsgi.version': (1, 0), 
     'wsgi.multithread': False, 'wsgi.multiprocess': False, 
     'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 
     'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 
     'SERVER_NAME': 'PC-Yang', 'SERVER_PORT': '8888', 'REQUEST_METHOD': 'GET', 
    'PATH_INFO': '/websocket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 
    'REMOTE_ADDR': '192.168.16.14', 'REMOTE_PORT': '61539', 'HTTP_HOST': '192.168.16.14:8888', 
    'HTTP_CONNECTION': 'keep-alive', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache', 
    'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 
    'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', 
    'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', 
    'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 
    'wsgi.input': <gevent.pywsgi.Input object at 0x03A9DC00>, 
     'wsgi.input_terminated': True, 'werkzeug.request': <Request 'http://192.168.16.14:8888/websocket' [GET]>
    }
http-environ

http-headers:

'''
    Host: 192.168.16.14:8888
    Connection: keep-alive
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
'''
http-headers

websocket-environ: 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x03A9DC00>,websocket连接

'''
    {
     'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6', 
     'SCRIPT_NAME': '', 'wsgi.version': (1, 0), 'wsgi.multithread': False, 
     'wsgi.multiprocess': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 
     'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 
     'SERVER_NAME': 'PC-Yang', 'SERVER_PORT': '8888', 'REQUEST_METHOD': 'GET', 
    'PATH_INFO': '/websocket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 
    'REMOTE_ADDR': '192.168.16.14', 'REMOTE_PORT': '61591', 'HTTP_HOST': '192.168.16.14:8888', 
    'HTTP_CONNECTION': 'Upgrade', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache', 
    'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', 
    'HTTP_UPGRADE': 'websocket', 'HTTP_ORIGIN': 'http://192.168.16.14:8888', 'HTTP_SEC_WEBSOCKET_VERSION': '13', 
    'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 
    'HTTP_SEC_WEBSOCKET_KEY': 'Oyfq0MCEBnsypKstjjRvYg==', 
    'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits', 
    'wsgi.input': <gevent.pywsgi.Input object at 0x03A9DCA8>, 
    'wsgi.input_terminated': True, 'wsgi.websocket_version': '13', 
    
    'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x03A9DC00>, 
    
    'werkzeug.request': <Request 'http://192.168.16.14:8888/websocket' [GET]>
    }
'''
websocket-environ

websocket-headers:     Upgrade: websocket   #websocket请求中的标识

'''
    Host: 192.168.16.14:8888
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    
    Upgrade: websocket   #websocket请求中的标识
    
    Origin: http://192.168.16.14:8888
    Sec-Websocket-Version: 13
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Sec-Websocket-Key: Oyfq0MCEBnsypKstjjRvYg==
    Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits
'''
websocket-headers

 

(1)基于websocket+flask实现的群聊无昵称即时通信

  flask_websocket(MUC_Nonick).py  

 1 '''
 2 基于websocket+flask实现的群聊无昵称即时通信
 3 设计列表client_list = []来存储客户端与服务器的连接,
 4 服务收到任意客户端的信息(信息时),对连接存储列表进行遍历获取每个连接,直接进行转发
 5 '''
 6 from flask import Flask,
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值