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="width: 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="width: 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 断开连接时,从用户字典中剔除用户信息。

 

创建服务端

 

posted @ 2019-02-27 21:47  CLuke  阅读(286)  评论(0编辑  收藏  举报
Live2D