Websocket
1.轮询:
- HTTP协议的轮询(无状态) TCP三次握手
- 缺陷:
- 信息不能及时传达
- 客户端和服务器都浪费很多的资源
- HTTP无法跟踪定位客户端
2.长轮询:
- HTTP协议的长轮询
- 可能出现: HTTP请求超时, HTTP请求断开
- 缺陷:
3.长连接:
Flask建立长连接
1.准备阶段
- Web - Socket
- pip install gevent-websocket
2.基本流程
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket.server import WSGIServer
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)
http_server.serve_forever()
Flask+WebSocket创建一个简易的web聊天室
群聊室
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")
client_list.append(sock)
print(client_list)
while 1:
try:
msg = sock.receive()
except:
client_list.remove(sock)
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)
http_server.serve_forever()
<!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">
var ws = new WebSocket("ws://127.0.0.1:9527/ws");
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>
私聊室
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)
if not sock:
return "请使用ws协议连接!"
client_dict[username] = sock
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)
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()
<!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 () {
var username = document.getElementById("username").value;
ws = new WebSocket("ws://127.0.0.1:9527/ws/"+username);
ws.onopen = function () {
alert("欢迎登入聊天室!")
};
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));
}
</script>
</html>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步