zoukankan      html  css  js  c++  java
  • WebSocket

    一、WebSocket简介

    • 顾名思义即:Web + Socket,它是一中TCP协议,当客户端和服务器完成握手,建立连接后,ws 就如普通 socket 一样,在两者之间进行通信。
    • WebSocket 是HTML5的新功能,在HTML5之前,HTML还不支持WebSocket,当时如果要进行实时的内容更新则需要使用到轮询技术。

    轮询

    客户端一直发请求,服务端一直收请求,直到服务端给客户端响应。

    • 优点:响应及时

    • 缺点:消耗两端资源,非常严重,占用大量带宽

    长轮询

    客户端发起请求,服务收到请求,内部进行轮询等待

    • 优点:响应及时,节省资源,不会一直发送求情和响应

    • 缺点:服务器资源消耗

    二、如何使用WebSocket

    1. Flask+WebSocket(基础版low)

    from flask import Flask,request,render_template
    from geventwebsocket.websocket import WebSocket  # Websocket语法提示
    from geventwebsocket.handler import WebSocketHandler  # 处理Websocket请求头
    from gevent.pywsgi import WSGIServer  # 在处理http请求时还能处理websocket请求
    
    app = Flask(__name__)
    
    @app.route("/index")
    def index():
    
        return render_template("ws.html")
    
    
    @app.route("/web")
    def web():
        # 获取用户的socket连接, 并开启语法提示
        user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
        if not user_socket:
            return "请使用websocket方式连接"
        while True:
            # 获取用户发送的信息
            user_msg = user_socket.receive()
            print(user_msg)
            data = input("回复:").strip()
            user_socket.send(data)
    
    
    if __name__ == '__main__':
        # app.run("0.0.0.0", 8000, debug=True)
        # 当请求进来之后,如果是websocket请求交给WebSocketHandler处理之后再交给APP处理。
        http_serv = WSGIServer(("0.0.0.0",8000), app,handler_class=WebSocketHandler)
        http_serv.serve_forever()
    Python代码
    <script type="application/javascript">
        var ws = new WebSocket("ws://127.0.0.1:8000/web");
        ws.onopen = function () {
            ws.send("加油")
        };
    
        ws.onmessage = function (serv_msg) {
            console.log(serv_msg.data)
        }
    </script>
    HTML代码

    2. Flask+WebSocket(单聊带昵称low)

    from flask import Flask, request, render_template
    from geventwebsocket.websocket import WebSocket
    from geventwebsocket.websocket import WebSocketError
    from geventwebsocket.handler import WebSocketHandler
    from gevent.pywsgi import WSGIServer
    
    import json
    
    app = Flask(__name__)
    
    
    @app.route("/index")
    def index():
        return render_template("ws.html")
    
    
    user_socket_list = []
    user_socket_dict = {}
    
    
    @app.route("/ws/<username>")
    def ws(username):
        user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
        if not user_socket:
            return "请使用WebSocket方式连接"
        user_socket_dict[username] = user_socket
        print(user_socket_dict)
        while True:
            try:
                user_msg = user_socket.receive()
                # 将字符类型的字典,转换为字典类型
                user_msg =eval(user_msg)
                print()
                for user_name, u_socket in user_socket_dict.items():
                    if user_name == user_msg["to_user"]:
                        who_send_msg = {
                            "send_user": username,
                            "send_msg": user_msg['send_msg']
                        }
                        u_socket.send(json.dumps(who_send_msg))
            except WebSocketError as e:
                user_socket_dict.pop(username)
                print(e)
                return "断开连接"
    
    
    
    
    
    if __name__ == '__main__':
        # app.run("0.0.0.0",8000,debug=True)
        http_serv = WSGIServer(("0.0.0.0", 8000), app, handler_class=WebSocketHandler)
        http_serv.serve_forever()
    Python代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    你是谁:<input type="text" id="username">
    给谁发:<input type="text" id="to_user">
    <button id="create_ws" onclick="go_to()">创建ws连接</button>
    <div style=" 400px; height: 300px;" id="chat_window">
    
    </div>
    <div>
        <input type="text" id="send_msg">
        <button id="btn_send">发送消息</button>
    </div>
    </body>
    <script type="application/javascript">
        var ws_url = "ws://127.0.0.1:8000/ws/";
        var ws = null;
        //    ws.onopen = function () {
        //        ws.send("你好!")
        //    };a
        function go_to() {
            var username = document.getElementById("username");
            ws = new WebSocket(ws_url + username.value);
    
            ws.onmessage = function (serv_msg) {
                msg = JSON.parse(serv_msg.data);
                console.log(msg);
                create_chat("y",msg);
            };
        }
    
    
        function create_chat(self, content) {
            if (self == "w") {
                self = "right";
                var spantag = document.createElement("span");
                spantag.innerText = content.send_msg;
                var spantag1 = document.createElement("span");
                spantag1.innerText = ":我";
            } else {
                self = "left";
                var spantag = document.createElement("span");
                spantag.innerText = content.send_user + ":";
                var spantag1 = document.createElement("span");
                spantag1.innerText = content.send_msg;
    
            }
    
            var divtag = document.createElement("div");
            divtag.style = "text-align:" + self;
    
            divtag.appendChild(spantag);
            divtag.appendChild(spantag1);
            var chat_window = document.getElementById("chat_window");
            chat_window.appendChild(divtag);
        }
    
        document.getElementById("btn_send").addEventListener("click", function () {
            var send_msg = document.getElementById("send_msg");
            var to_user = document.getElementById("to_user");
            send_msg_json = {
                send_msg:send_msg.value,
                to_user :to_user.value
            };
            ws.send(JSON.stringify(send_msg_json));
    
            var s_msg = {send_msg:send_msg.value};
            create_chat("w", s_msg);
            send_msg.value = "";
        })
    
    </script>
    </html>
    HTML代码

    3.Flask+WebSocket(群聊带昵称low)

    from flask import Flask, request, render_template
    from geventwebsocket.websocket import WebSocket
    from geventwebsocket.websocket import WebSocketError
    from geventwebsocket.handler import WebSocketHandler
    from gevent.pywsgi import WSGIServer
    
    import json
    
    app = Flask(__name__)
    
    
    @app.route("/index")
    def index():
        return render_template("ws.html")
    
    
    user_socket_list = []
    user_socket_dict = {}
    
    
    @app.route("/ws/<username>")
    def ws(username):
        user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
        if not user_socket:
            return "请使用WebSocket方式连接"
        user_socket_dict[username] = user_socket
        print(user_socket_dict)
        while True:
            try:
                user_msg = user_socket.receive()
                for user_name, u_socket in user_socket_dict.items():
                    who_send_msg = {
                        "send_user": username,
                        "send_msg": user_msg
                    }
                    if user_socket == u_socket:
                        continue
                    u_socket.send(json.dumps(who_send_msg))
            except WebSocketError as e:
                user_socket_dict.pop(username)
                print(user_socket_dict)
                print(e)
    
    
    if __name__ == '__main__':
        # app.run("0.0.0.0",9527,debug=True)
        http_serv = WSGIServer(("0.0.0.0", 8000), app, handler_class=WebSocketHandler)
        http_serv.serve_forever()
    Python代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    你是谁:<input type="text" id="username">
    <button id="create_ws" onclick="go_to()">创建ws连接</button>
    <div style=" 400px; height: 300px;" id="chat_window">
    
    </div>
    <div>
        <input type="text" id="send_msg">
        <button id="btn_send">发送消息</button>
    </div>
    </body>
    <script type="application/javascript">
        var ws_url = "ws://127.0.0.1:8000/ws/";
        var ws = null;
    
        function go_to() {
            var username = document.getElementById("username");
            ws = new WebSocket(ws_url + username.value);
    
            ws.onmessage = function (serv_msg) {
                msg = JSON.parse(serv_msg.data);
                create_chat("y",msg);
            };
        }
    
        function create_chat(self, content) {
            if (self == "w") {
                self = "right";
                var spantag = document.createElement("span");
                spantag.innerText = content.send_msg;
                var spantag1 = document.createElement("span");
                spantag1.innerText = ":我";
            } else {
                self = "left";
                var spantag = document.createElement("span");
                spantag.innerText = content.send_user + ":";
                var spantag1 = document.createElement("span");
                spantag1.innerText = content.send_msg;
            }
    
            var divtag = document.createElement("div");
            divtag.style = "text-align:" + self;
    
            divtag.appendChild(spantag);
            divtag.appendChild(spantag1);
            var chat_window = document.getElementById("chat_window");
            chat_window.appendChild(divtag);
        }
    
        document.getElementById("btn_send").addEventListener("click", function () {
            var send_msg = document.getElementById("send_msg");
            ws.send(send_msg.value);
            var s_msg = {send_msg:send_msg.value};
            create_chat("w", s_msg);
            send_msg.value = "";
        })
    
    </script>
    </html>
    HTML代码

    三、WebSocket + Flask实现实时更新

    实现思路:

    1. 客户端发起 ws 连接请求。
    2. 服务器响应,并以key、vlue形式存储用户与用户地址。

    3. 当某一 ws 向服务器发送信息时,服务器遍历字典中,向里面每一个用户发送信息。

    4. ws 断开连接时,从用户字典中剔除用户信息。

    创建服务端

  • 相关阅读:
    确定方法返回位置为泛型的类型
    centos7 svn服务器搭建
    centos7优化启动项,关闭一些不必要开启的服务
    使用windos电脑模拟搭建集群(四)web环境 linux+nginx+jdk+tomcat
    java使用BeanUtils封装file类型表单数据到一个对象中
    表单隐藏域
    本地yum仓库的搭建
    centos7 挂载exfat格式的u盘
    三体
    海盗分金的故事
  • 原文地址:https://www.cnblogs.com/Dream-huang/p/9513817.html
Copyright © 2011-2022 走看看