• flask 第五章 WebSocket GeventWebsocket 单聊群聊 握手 解密 加密


    1.WebSocket

    首先我们来回顾一下,我们之前用socket学习过的项目有:

      1.django

      2.flask

      3.FTP - 文件服务

    HTTP - TCP (特点):

      1.一次请求,一次响应,然后断开

      2.客户端永远处于主动状态

      3.服务端永远处于被动状态

      4.HTTP请求是无状态的 -- 在服务器不保存客户端的信息

      5.由于HTTP请求是无状态的,所以服务器无法主动找到客户端

       优点 : 

        1.速度快 

        2.信息安全

        3.不是特别占用资源

    1.轮询:

      客户端不停的向服务端发送请求,服务端不停的向客户端响应,直到客户端拿到数据为止.

      劣势:

        1.服务端和客户端双端资源浪费

        2.带宽资源占用(带宽 : 网络连接时所能传送的最大数据流速)

        3.不能保证数据的实时性

    2. 长轮询:

      客户端向服务端发送一个请求,服务端保持这个请求,不返回值就不响应,一定时间后,服务器抛弃这个请求或者是返回. 客户端收到请求后,立即再次发起保持连接.

    在这里我们类比一个实例:

      你去传达室问大爷有没有快递,大爷款待你喝茶(喝茶的时候就相当于保持连接),如果中途你想去厕所(去厕所就相当于是断开了连接),回来之后继续喝茶(再次建立保持连接).

      劣势:

        1.相比于轮询方式,长轮询方式只是浪费了服务器的资源

        2.无法保证是数据实时性

      优势:

        1.相比于轮询方式,他节省了客户端的资源

        2.保证数据有效

    3.长连接

      永久的保持连接(现在我们用的基本上都是长连接)

      劣势:

          对服务器的CPU要求比较高

      优势:

        1.节省了大量的资源(客户端和服务端的资源都节省了)

        2.数据实时有效性

        3.带宽资源几乎不占用

    WebSocket协议 : ws协议 ws://127.0.0.1 用JavaScript封装客户端

      三方 : geventWebsocket Flask

      web框架 : 用来进行Http请求的处理(握手)

    4.单聊 

    .py文件的代码如下:

    import json
    
    from flask import Flask, render_template, request
    from geventwebsocket.handler import WebSocketHandler
    from gevent.pywsgi import WSGIServer
    from geventwebsocket.websocket import WebSocket
    from geventwebsocket.exceptions import WebSocketError
    
    app = Flask(__name__)
    
    user_socket_dict = {}
    
    
    @app.route('/my_app')
    def my_app():
        return render_template('myapp.html')
    
    
    @app.route('/my_ws/<username>')
    def my_ws(username):
        user_socket = request.environ.get( 'wsgi.websocket')  
        # 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x00000206FCDC1528>,
        user_socket_dict[username] = user_socket  # type:WebSocket
        # print(user_socket_dict)
        while 1:
            try:
                # 阻塞等待消息数据
                msg = user_socket.receive()
                # 将接收到的消息反序列化成字典
                msg_dict = json.loads(msg)
                # print(msg)
                to_user = msg_dict.get('to_user')
                to_user_socket = user_socket_dict.get(to_user)
                to_user_socket.send(msg)
            except WebSocketError:
                user_socket_dict.pop(username)
                return '有个地方错了'
    
    
    if __name__ == '__main__':
        http_server = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
        http_server.serve_forever()

    myapp.html 文件代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    你的名字:<input type="text" id="nkname">
    <button onclick="open_chat()">登录聊天室</button>
    <p>发送至<input type="text" id="to_user"></p>
    消息<input type="text" id="message">
    <button onclick="send_msg()">发送</button>
    <div id="chat_list">
    
    </div>
    </body>
    <script type="application/javascript">
        var ws = null;
    
        function open_chat() {
            var nkname = document.getElementById('nkname').value;
            ws = new WebSocket("ws://127.0.0.1:9527/my_ws/" + nkname);
            ws.onopen = function () {
                alert('欢迎' + nkname + '登录对骂平台!!')
            };
            ws.onmessage = function (EventMessage) {
                var chat = JSON.parse(EventMessage.data);
                var p = document.createElement('p');
                p.style.cssText = 'width : 250px; text-align:left';
                p.innerText = chat.from_user + '-->' + chat.message;
                document.getElementById('chat_list').appendChild(p);
            };
            ws.onclose = function () {
                console.log('断开连接了,啥情况啊? 搞事情啊');
            };
        }
    
        function send_msg() {
            var message = document.getElementById('message').value;
            var from_user = document.getElementById('nkname').value;
            var to_user = document.getElementById('to_user').value;
            var send_str = {
                message: message,
                from_user: from_user,
                to_user: to_user
            };
            ws.send(JSON.stringify(send_str));
            var p = document.createElement('p');
            p.style.cssText = " 250px;text-align: right";
            p.innerText = send_str.message + "<-我";
            document.getElementById('chat_list').appendChild(p);
        }
    
    </script>
    </html>

    5.群聊

    .py文件代码如下: 

    from geventwebsocket.handler import WebSocketHandler
    from gevent.pywsgi import WSGIServer
    from geventwebsocket.websocket import WebSocket
    from geventwebsocket.exceptions import WebSocketError
    
    from flask import Flask,render_template,request
    
    app = Flask(__name__)
    
    user_socket_list = []
    
    @app.route("/my_app")
    def my_app():
        return render_template("my_app.html")
    
    @app.route("/my_ws")
    def my_ws():
        user_socket = request.environ.get("wsgi.websocket") 
        # type:WebSocket
        user_socket_list.append(user_socket)
        # print(len(user_socket_list),user_socket_list)
        while 1:
            try:
                msg = user_socket.receive() # 阻塞等待消息数据
            except WebSocketError:
                user_socket_list.remove(user_socket)
                return "good bye"
            for u in user_socket_list:
                if u == user_socket:
                    continue
                try:
                    u.send(msg)
                except :
                    continue
    
    if __name__ == '__main__':
        # app.run()
        http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler)
        http_serv.serve_forever()

    myapp.html文件代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <input type="text" id="message"><button onclick="send_message()">发送</button>
        <div id="chat_list">
    
        </div>
    </body>
    <script type="application/javascript">
        var ws = new WebSocket("ws://192.168.14.200:9527/my_ws");
        ws.onmessage = function (eventMessage) {
            // document.getElementById("chat_list").innerHTML += "<p>" + eventMessage.data + "</p>";
            var p = document.createElement("p");
            p.innerText = eventMessage.data;
            document.getElementById("chat_list").appendChild(p);
        };
    
        function send_message() {
            var message = document.getElementById("message").value;
            ws.send(message);
        }
    
    </script>
    </html>
  • 相关阅读:
    重构改善既有代码设计--重构手法 之重新组织你的函数总结
    重构改善既有代码设计--重构手法09:Substitute Algorithm (替换算法)
    重构改善既有代码设计--重构手法08:Replace Method with Method Object (以函数对象取代函数)
    重构改善既有代码设计--重构手法07:Remove Assignments to Parameters (移除对参数的赋值)
    重构改善既有代码设计--重构手法06:Split Temporary Variable (分解临时变量)
    重构改善既有代码设计--重构手法05:Introduce Explaining Variable (引入解释性变量)
    重构改善既有代码设计--重构手法04:Replace Temp with Query (以查询取代临时变量)
    leetcode-441-Arranging Coins
    leetcode-438-Find All Anagrams in a String
    leetcode-434-Number of Segments in a String
  • 原文地址:https://www.cnblogs.com/zty1304368100/p/10712550.html
Copyright © 2020-2023  润新知