python | 同时使用flask和websockets
python | 同时使用flask和websockets
一个非常简单的解决方案
代码如下:
'''
author: Mz1
一个脚本启动的多功能聊天室
架构:
在新线程中启动flask
在主线程中启动websockets
'''
# index.html
index_html = '''
<!DOCTYPE html>
<html>
<head>
<title>PyChatRoom@Mz1</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0,
maximum-scale=1.0,
user-scalable=no">
<!-- 引入jquery和bootstrap -->
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class='container'>
<h4>当前聊天室: {{ _path }}</h4>
<input id="text" value="">
<input type="submit" value="send" onclick="start()">
<input type="submit" value="close" onclick="close()">
<div id="msg"></div>
</div>
</body>
<script>
/**
0:未连接
1:连接成功,可通讯
2:正在关闭
3:连接已关闭或无法打开
*/
//创建一个webSocket 实例
var _url = "ws://127.0.0.1:2333";
var webSocket = new WebSocket(_url);
webSocket.onerror = function (event){
onError(event);
};
// 打开websocket
webSocket.onopen = function (event){
onOpen(event);
};
//监听消息
webSocket.onmessage = function (event){
onMessage(event);
};
webSocket.onclose = function (event){
onClose(event);
}
//关闭监听websocket
function onError(event){
document.getElementById("msg").innerHTML = "<p>close</p>";
console.log("error"+event.data);
};
function onOpen(event){
console.log("open:"+sockState());
document.getElementById("msg").innerHTML = "<p>Connect to Service</p>";
document.getElementById("msg").innerHTML += '<p>连接到: '+_url+'</p>';
};
function onMessage(event){
console.log("onMessage");
document.getElementById("msg").innerHTML += "<p>response: "+event.data+"</p>"
};
function onClose(event){
document.getElementById("msg").innerHTML = "<p>close</p>";
console.log("close: "+sockState());
webSocket.close();
}
function sockState(){
var status = ['未连接','连接成功,可通讯','正在关闭','连接已关闭或无法打开'];
return status[webSocket.readyState];
}
function start(event){
console.log(webSocket);
var msg = document.getElementById('text').value;
document.getElementById('text').value = '';
console.log("send:"+sockState());
console.log("msg="+msg);
webSocket.send("msg="+msg);
document.getElementById("msg").innerHTML += "<p>request"+msg+"</p>"
};
function close(event){
webSocket.close();
}
</script>
</html>
'''
from flask import Flask, render_template_string
import asyncio
import websockets
import threading
import time
# Websocket服务端
class WebsocketChatServer():
def __init__(self):
pass
async def run(self, port):
start_server = websockets.serve(self.handler, "", port)
await start_server
print(f' > server start ok! on port {port}')
await asyncio.Future() # run forever
async def handler(self, websocket, path):
print(path)
while True:
try:
msg = await websocket.recv()
except websockets.ConnectionClosedOK:
break
print(f"recv: {msg}")
print(' > close a connection')
# 初始化和定义flask
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
if path == '':
path = 'home' # 默认聊天室
return render_template_string(index_html, _path=path) # 捕获一切路径,返回拼接的html文件
# 启动函数
def main():
# 在新线程中启动flask
print(app.url_map)
flask_thread = threading.Thread(target=app.run, args=('0.0.0.0', 5000))
flask_thread.start()
# 启动websocket server
print('> starting server...')
server = WebsocketChatServer()
tasks = [
server.run(2333),
]
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(asyncio.wait(tasks))
except KeyboardInterrupt:
for task in asyncio.Task.all_tasks():
task.cancel()
loop.stop()
loop.run_forever()
loop.close()
if __name__ == '__main__':
main()
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/16774938.html
如果有问题可以在下方评论或者email:mzi_mzi@163.com