码迷,mamicode.com
首页 > 其他好文 > 详细

Flask学习Ⅳ

时间:2020-09-24 21:41:19      阅读:27      评论:0      收藏:0      [点我收藏+]

标签:document   tle   消息   open   rev   __name__   替换   log   title   

Websocket

1.轮询:

  • HTTP协议的轮询(无状态) TCP三次握手
  • 缺陷:
    • 信息不能及时传达
    • 客户端和服务器都浪费很多的资源
    • HTTP无法跟踪定位客户端

2.长轮询:

  • HTTP协议的长轮询
  • 可能出现: HTTP请求超时, HTTP请求断开
  • 缺陷:
    • 消息实时性不高
    • 占用资源
    • 客户端线程资源占用

3.长连接:

  • 优点:
    • 消息及时
    • 一次连接不会断开
  • 缺陷:
    • 占用空间小了,CPU和内存消耗大

Flask建立长连接

1.准备阶段

  • Web - Socket
  • pip install gevent-websocket

2.基本流程

from geventwebsocket.handler import WebSocketHandler	#ws协议处理
from geventwebsocket.server import WSGIServer	#替换Flask原有的WSGI
from geventwebsocket.websocket import WebSocket	#语法提示(非必须)

from flask import Flask

app = Flask(__name__)

if __name__ == ‘__main__‘:
   http_server = WSGIServer(("0.0.0.0", 9527), app, handler_class=WebSocketHandler)	#监听ip和port,app,ws协议处理
   http_server.serve_forever()

Flask+WebSocket创建一个简易的web聊天室

群聊室

  • py文件
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.server import WSGIServer
from geventwebsocket.websocket import WebSocket

from flask import Flask, request

app = Flask(__name__)

client_list = []

@app.route("/ws")
def ws():
    sock = request.environ.get("wsgi.websocket")  # type:WebSocket
    client_list.append(sock)
    print(client_list)
    while 1:
        try:
            msg = sock.receive()    # 检查连接连接是否异常
        except:
            client_list.remove(sock)	# 连接异常则从连接列表中删除该socket
            break
        for client in client_list:
            if client == sock:
                continue
            try:
                client.send(msg)	# 检查信息是否成功发出,若无这说明该连接已经断开
            except:
                continue

    return "200 OK"

if __name__ == ‘__main__‘:
    http_server = WSGIServer(("0.0.0.0", 9527), app, handler_class=WebSocketHandler)  # environ对象交给app(flask)处理
    http_server.serve_forever()
  • html文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>群聊室</title>
</head>
<body>
<h1>欢迎进入群聊室!</h1>
<input type="text" id="text"> <button id="send">点击发送</button>
<div id="content_list"></div>
</body>
<script type="application/javascript">
    //新建ws连接
    var ws = new WebSocket("ws://127.0.0.1:9527/ws");
    //接收到消息生成p标签并展示在页面上
    ws.onmessage = function (eventMessage) {
        var msg = eventMessage.data;
        var p = document.createElement("p");
        p.innerText = msg;
        document.getElementById("content_list").appendChild(p);
    };
	//在页面上输入消息并发送
    document.getElementById("send").onclick = function () {
        var msg = document.getElementById("text").value;
        ws.send(msg);
    }

</script>
</html>

私聊室

  • py文件
import json

from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.server import WSGIServer
from geventwebsocket.websocket import WebSocket

from flask import Flask, request, render_template

app = Flask(__name__)

client_dict = {}	#改用字典,能显示发送消息人的用户名

@app.route("/ws/<username>")	#动态参数获取用户名
def ws(username):
    sock = request.environ.get("wsgi.websocket", None)   # type:WebSocket
    # 1.非ws协议上来的请求 None
    # 2.ws协议认证失败
    if not sock:
        return "请使用ws协议连接!"
    client_dict[username] = sock    # 用户名:socket套接字
    print(len(client_dict), client_dict)

    while 1:
        msg = sock.receive()
        msg_dict = json.loads(msg)
        recipient = msg_dict.get("recipient")   #找到接收方
        recipient_sock = client_dict.get(recipient)	#根据接收方,从client_dict拿出对应socket
        recipient_sock.send(msg)    #原封不动返回给接收方

@app.route("/")
def index():
    return render_template("chat.html")

if __name__ == ‘__main__‘:
    http_server = WSGIServer(("0.0.0.0", 9527), app, handler_class=WebSocketHandler)
    http_server.serve_forever()
  • html文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>聊天室</title>
</head>
<body>
<h1>欢迎进入私聊室!</h1>
用户名: <input type="text" id="username"> <button id="login">登入</button>

<p>给 <input type="text" id="recipient"> 发送 <input type="text" id="text"> <button id="send">点击发送</button></p>

<div id="content_list"></div>
</body>
<script type="application/javascript">
    var ws = null;
    document.getElementById("login").onclick = function () {
        //获取用户名作为动态参数传递给server端
        var username = document.getElementById("username").value;
        //修改ws连接
        ws = new WebSocket("ws://127.0.0.1:9527/ws/"+username);
        ws.onopen = function () {
            alert("欢迎登入聊天室!")
        };
        //接收消息并新建p标签显示在页面上
        ws.onmessage = function (eventMessage) {
            var msg = JSON.parse(eventMessage.data);
            console.log(msg)
            var p = document.createElement("p");
            p.innerText = msg.sender + ‘:‘ + msg.msg;
            document.getElementById("content_list").appendChild(p);
        };
    }
    //发送消息
    document.getElementById("send").onclick = function () {
        var msg = document.getElementById("text").value;
        var sender = document.getElementById("username").value;
        var recipient = document.getElementById("recipient").value;
        var detail = {
            "msg":msg,
            "sender":sender,
            "recipient":recipient
        };
        console.log(detail)
        ws.send(JSON.stringify(detail));    //object(字典)不能直接传输
    }

</script>
</html>

Flask学习Ⅳ

标签:document   tle   消息   open   rev   __name__   替换   log   title   

原文地址:https://www.cnblogs.com/straightup/p/13722407.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!