Flask和WebSocket

WebSocket介绍

概念

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

当你获取 Web Socket 连接后,你可以通过 send()方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

详情:https://www.runoob.com/html/html5-websocket.html

WebSocket实现长连接

连接保持 - Http 发起请求再请求中写一个协议 - WebSocket - 服务器收到Websocket请求 ,自动保持此连接 - 永久不断开,除非主动断开 - 可以通过此连接主动找到客户端

使用方法:

按照第三方包

pip3 install gevent-websocket

导入

from geventwebsocket.handler import WebSocketHandler  # 提供WS协议处理
from geventwebsocket.server import WSGIServer  # 承载服务
from geventwebsocket.websocket import WebSocket  # 语法提示

启动

if __name__ == '__main__':
    http_serve = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
    http_serve.serve_forever()
不再是之前的app.run()了。

后端操作

user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
# 这里的# type:WebSocket就是让这个user_socket有WebSocket语法提示
msg = user_socket.receive()
# 接收数据
print(msg)

前端操作(JavaScript)

var ws = new WebSocket("ws://127.0.0.1:9527/my_socket");
// 定义WebSocket连接请求
ws.onmessage = function (eventMessage) {
    console.log(eventMessage.data);
};

基于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():
    user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
    if user_socket:
        user_socket_list.append(user_socket)
        print(len(user_socket_list), user_socket_list)
    while True:
        msg = user_socket.receive()
        print(msg)
        for u_socket in user_socket_list:
            try:
                u_socket.send(msg)
            except:
                continue


@app.route('/group_chat')
def group_chat():
    return render_template('群聊.html')


if __name__ == '__main__':
    http_serve = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
    http_serve.serve_forever()
群聊.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>群聊</title>
</head>
<body>
<input type="text" id="content">
<button onclick="send_msg()">提交</button>

<div id="chat_list"></div>

<script type="application/javascript">
    var ws = new WebSocket("ws://127.0.0.1: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>

</body>
</html>
群聊.html

群聊(有昵称)

from flask import Flask, request, render_template
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.server import WSGIServer
from geventwebsocket.websocket import WebSocket

app = Flask(__name__)

user_socket_dict = {}


@app.route("/my_socket/<username>")
def my_socket(username):
    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)
    while True:
        msg = user_socket.receive()
        print(msg)
        for u_socket in user_socket_dict.values():
            print(user_socket)
            try:
                u_socket.send(msg)
            except:
                continue


@app.route('/group_chat')
def group_chat():
    return render_template('有昵称的群聊.html')


if __name__ == '__main__':
    http_serve = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
    http_serve.serve_forever()
群聊2.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>昵称群聊</title>
</head>
<body>
设置昵称:<input type="text" id="username">
<button onclick="loginGc()">确定</button>
<br>
<input type="text" id="content">
<button onclick="sendMsg()">提交</button>

<div id="chat_list"></div>

<script type="application/javascript">
    var ws = null;


    function loginGc() {
        var username = document.getElementById('username').value;
        ws = new WebSocket("ws://192.168.16.35: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 sendMsg() {
        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>

</body>
</html>
有昵称的群聊.html

私聊

import json

from flask import Flask, request, render_template
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.server import WSGIServer
from geventwebsocket.websocket import WebSocket

app = Flask(__name__)

user_socket_dict = {}


@app.route("/my_socket/<username>")
def my_socket(username):
    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)
    while True:
        msg = json.loads(user_socket.receive())
        to_user_nick = msg.get('to_user')
        to_user_socket = user_socket_dict.get(to_user_nick)
        to_user_socket.send(json.dumps(msg))


@app.route('/sl')
def sl():
    return render_template('私聊.html')


if __name__ == '__main__':
    http_serve = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
    http_serve.serve_forever()
私聊.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>私聊</title>
</head>
<body>
设置昵称:<input type="text" id="username">
<button onclick="loginGc()">确定</button>
<br><input type="text" id="to_user">发送<input type="text" id="content">
<button onclick="sendMsg()">发送</button>

<div id="chat_list"></div>

<script type="application/javascript">
    var ws = null;


    function loginGc() {
        var username = document.getElementById('username').value;
        ws = new WebSocket("ws://192.168.16.35: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 sendMsg() {
        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>

</body>
</html>
私聊.html

 

posted @ 2019-07-15 15:25  blog_wu  阅读(478)  评论(0编辑  收藏  举报