zoukankan      html  css  js  c++  java
  • 长连接 Websocket


    import json from flask import Flask,request,render_template from geventwebsocket.handler import WebSocketHandler # 提供WS协议处理 from geventwebsocket.server import WSGIServer # 承载服务 from geventwebsocket.websocket import WebSocket # 语法提示 app = Flask(__name__) @app.route(" ") def (): return if __name__ == '__main__': # app.run("0.0.0.0",9527) http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) ###WebSocketHandler 既能处理Http请求也能处理 Websocket请求 http_serv.serve_forever()

      

    群聊1(。py)

     客户端
    # 服务端
    # Http  Flask 浏览器
    # Websocket GeventWebsocket+Flask 客户端JavaScript(Websocket客户端)
    
    from flask import Flask,request,render_template
    from geventwebsocket.handler import WebSocketHandler  # 提供WS协议处理
    from geventwebsocket.server import WSGIServer  # 承载服务
    from geventwebsocket.websocket import WebSocket  # 语法提示
    
    app = Flask(__name__)
    
    user_socket_list = []
    
    @app.route("/my_socket")
    def my_socket():
        # 获取当前客户端与服务器的Socket连接  request.environ 获取的是请求的原始信息
        user_socket = request.environ.get("wsgi.websocket") # type:WebSocket 
        ###(<geventwebsocket.websocket.WebSocket object at 0x000001EC0B150E18>)   websocket连接

      if user_socket: user_socket_list.append(user_socket) print(len(user_socket_list),user_socket_list) # print(user_socket,"OK 连接已经建立好了,接下来发消息吧")

      while 1: msg = user_socket.receive() #服务器等待 客户端发完消息往下处理 不发消息等待 print(msg) for usocket in user_socket_list: try: usocket.send(msg) except: continue @app.route("/gc") def gc(): return render_template("gc.html") if __name__ == '__main__': # app.run("0.0.0.0",9527) http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) http_serv.serve_forever()
    群聊1 。html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>群聊</title>
    </head>
    <body>
    <p><input type="text" id="content"><button onclick="send_msg()">发送</button></p>

    <div id="chat_list">

    </div>
    </body>
    <script type="application/javascript">


    var ws = new WebSocket("ws://192.168.16.40:9527/my_socket");
    // 监听电话

    /*在前端显示内容*/
    ws.onmessage = function (eventMessage) {
    console.log(eventMessage.data);
    var p = document.createElement("p");
    p.innerText = eventMessage.data;###(发出的内容)
    document.getElementById("chat_list").appendChild(p);
    };

    /*把前端的内容发送到后端*/
    function send_msg() {
    var content = document.getElementById("content").value;
    ws.send(content);# 发出去 后端收
    };

    </script>
    </html>

      

    群聊2.py

    # 客户端
    # 服务端
    # Http  Flask 浏览器
    # Websocket GeventWebsocket+Flask 客户端JavaScript(Websocket客户端)
    import json
    
    from flask import Flask,request,render_template
    from geventwebsocket.handler import WebSocketHandler  # 提供WS协议处理
    from geventwebsocket.server import WSGIServer  # 承载服务
    from geventwebsocket.websocket import WebSocket  # 语法提示
    
    app = Flask(__name__)
    
    # user_socket_dict = {nicheng:lianjie}
    user_socket_dict = {}
    
    @app.route("/my_socket/<username>")
    def my_socket(username):
        # 获取当前客户端与服务器的Socket连接
        user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
        if user_socket:
            user_socket_dict[username] = user_socket
            print(len(user_socket_dict),user_socket_dict)                            #####以字典的形式存储姓名 和 websocket连接
        # print(user_socket,"OK 连接已经建立好了,接下来发消息吧")
        while 1:
            # msg = json.loads(user_socket.receive())
            msg = user_socket.receive()
            print(msg)
            for usocket in user_socket_dict.values():                    
                print(usocket)
                try:
                    usocket.send(msg)
                except:
                    continue
    
    
    
    
    @app.route("/gc")
    def gc():
        return render_template("gc.html")
    
    
    
    if __name__ == '__main__':
        # app.run("0.0.0.0",9527)
        http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler)
        http_serv.serve_forever()
    

      

    群聊2.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>群聊</title>
    </head>
    <body>
    <p>我的昵称:<input type="text" id="username">
      <button onclick="loginGc()">登录</button>
    </p>
    <p><input type="text" id="content">
      <button onclick="send_msg()">发送</button>
    </p>
    
    <div id="chat_list">
    
    </div>
    </body>
    <script type="application/javascript">
        var ws = null;
    
    
        function loginGc() {
            var username = document.getElementById("username").value;
            ws = new WebSocket("ws://192.168.12.63:9527/my_socket/" + username);
            // 监听电话                                                                                                   ##先走粉色登录 在发送给后端内容   再遍历发送到前端
            ws.onmessage = function (eventMessage) {
                console.log(eventMessage.data);
                str_obj = JSON.parse(eventMessage.data);
    
                var p = document.createElement("p");
                p.innerText = str_obj.from_user +" : "+str_obj.chat;
                document.getElementById("chat_list").appendChild(p);
            };
        };
    
        function send_msg() {
            var username = document.getElementById("username").value;
            var content = document.getElementById("content").value;
            var sendStr = {
                from_user:username,
                chat:content
            };
            ws.send(JSON.stringify(sendStr));
        };
    
    </script>
    </html>
    

    私聊.py

    # 客户端
    # 服务端
    # Http  Flask 浏览器
    # Websocket GeventWebsocket+Flask 客户端JavaScript(Websocket客户端)
    import json
    
    from flask import Flask,request,render_template
    from geventwebsocket.handler import WebSocketHandler  # 提供WS协议处理
    from geventwebsocket.server import WSGIServer  # 承载服务
    from geventwebsocket.websocket import WebSocket  # 语法提示
    
    app = Flask(__name__)
    
    # user_socket_dict = {nicheng:lianjie}
    user_socket_dict = {}
    
    @app.route("/my_socket/<username>")
    def my_socket(username):
        # 获取当前客户端与服务器的Socket连接
        user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
        if user_socket:
            user_socket_dict[username] = user_socket
            print(len(user_socket_dict),user_socket_dict)
        # print(user_socket,"OK 连接已经建立好了,接下来发消息吧")
       

    while 1: msg = user_socket.receive() msg_dict = json.loads(msg) # msg = user_socket.receive()

         to_user_nick = msg_dict.get("to_user") print(to_user_nick) to_user_socket = user_socket_dict.get(to_user_nick) to_user_socket.send(msg) @app.route("/sl") def sl(): return render_template("sl.html") if __name__ == '__main__': # app.run("0.0.0.0",9527) http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) http_serv.serve_forever()

      

    私聊。html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>私聊</title>
    </head>
    <body>
    <p>我的昵称:<input type="text" id="username">
      <button onclick="loginGc()">登录</button>
    </p>
    <p>给<input type="text" id="to_user">发送<input type="text" id="content">
      <button onclick="send_msg()">发送</button>
    </p>
    
    <div id="chat_list">
    
    </div>
    </body>
    <script type="application/javascript">
        var ws = null;
    
    
        function loginGc() {
            var username = document.getElementById("username").value;
            ws = new WebSocket("ws://192.168.75.1:9527/my_socket/" + username);
            // 监听电话
            ws.onmessage = function (eventMessage) {
                console.log(eventMessage.data);
                str_obj = JSON.parse(eventMessage.data);
    
                var p = document.createElement("p");
                p.innerText = str_obj.from_user +" : "+str_obj.chat;
                document.getElementById("chat_list").appendChild(p);
            };
        };
    
        function send_msg() {
            var username = document.getElementById("username").value;
            var to_user = document.getElementById("to_user").value;
            var content = document.getElementById("content").value;
            var sendStr = {
                from_user:username,
                to_user:to_user,
                chat:content
            };
            ws.send(JSON.stringify(sendStr));
        };
    
    </script>
    </html>
    

      

    http:
    headers:
    Host: 127.0.0.1:9527
    Connection: keep-alive
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    
    
    ws:
    headers:
    Host: 127.0.0.1:9527
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
    Upgrade: websocket == Websocket 请求 WebSocketHandler 处理的 Key
    Origin: http://localhost:63342
    Sec-Websocket-Version: 13
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    Sec-Websocket-Key: KttfJvW4Vt/KTuFudtOf2g==
    Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits
    

      

    2.GeventWebsocket + Flask
    Web(HTTP) + Socket (连接保持)
    Flask中运行Websocket - GeventWebsocket
    编码 
    
    WebSocketHandler 监听了 请求头中的?
    Http:
    env :
    {'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': 'DESKTOP-JNSGT4U', 'SERVER_PORT': '9527', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/my_socket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '51956', 'HTTP_HOST': '127.0.0.1:9527', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'wsgi.input': <gevent.pywsgi.Input object at 0x000001EA38EA94C8>, 'wsgi.input_terminated': True, 'werkzeug.request': <Request 'http://127.0.0.1:9527/my_socket' [GET]>}
    
    
    ws:
    {'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': 'DESKTOP-JNSGT4U', 'SERVER_PORT': '9527', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/my_socket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '52075', 'HTTP_HOST': '127.0.0.1:9527', 'HTTP_CONNECTION': 'Upgrade', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36', 'HTTP_UPGRADE': 'websocket', 'HTTP_ORIGIN': 'http://localhost:63342', 'HTTP_SEC_WEBSOCKET_VERSION': '13', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_SEC_WEBSOCKET_KEY': 'KttfJvW4Vt/KTuFudtOf2g==', 'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits', 'wsgi.input': <gevent.pywsgi.Input object at 0x000001EA38EA9B88>, 'wsgi.input_terminated': True, 'wsgi.websocket_version': '13', 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x000001EA38EEE2B8>, 'werkzeug.request': <Request 'http://127.0.0.1:9527/my_socket' [GET]>}
    

      

    3.长连接 客户端 和 服务器资源 消耗没有那么严重了
    连接保持 - Http 发起请求再请求中写一个协议 - WebSocket - 服务器收到Websocket请求 ,自动保持此连接 - 永久不断开,除非主动断开 - 可以通过此连接主动找到客户端
    
    
    
    
    优势:数据实时性
    劣势:服务器和客户端需要一个线程来等待消息
    服务器 完成 IO多路复用
    

      

  • 相关阅读:
    Ubuntu下ClickHouse安装
    redis.conf配置详解(转)
    php使用sftp上传文件
    ubuntu下安装nginx1.11.10
    cookie和session的区别
    linux下Redis主从复制
    linux-ubuntu 安装配置Redis
    php的常量
    Ubuntu防火墙配置
    技术资料
  • 原文地址:https://www.cnblogs.com/qj696/p/11252938.html
Copyright © 2011-2022 走看看