Python 3.x python socketio和Flask:如何停止后台线程中的循环?
在我的Flask应用程序中,我有一个类似的循环,由客户端发出的套接字消息启动:Python 3.x python socketio和Flask:如何停止后台线程中的循环?,python-3.x,flask,socket.io,Python 3.x,Flask,Socket.io,在我的Flask应用程序中,我有一个类似的循环,由客户端发出的套接字消息启动: @socketio.on('start') def my_start(): global thread if thread is None: thread = socketio.start_background_task(target=background_thread) def background_thread(): for i in range(1,10
@socketio.on('start')
def my_start():
global thread
if thread is None:
thread = socketio.start_background_task(target=background_thread)
def background_thread():
for i in range(1,100):
socketio.emit('my_mess',{'data': i})
if <**condition**>== True:
socketio.emit('aborted')
break
if <**condition**> == False:
socketio.emit('Success',{'data': '16.34 GB'})
else:
<**condition**> = False
@socketio.on('start'))
def my_start():
全局线程
如果线程为“无”:
线程=socketio.start\u background\u任务(目标=background\u线程)
def background_thread():
对于范围(1100)内的i:
emit('my_mess',{'data':i})
如果==真:
socketio.emit('中止')
打破
如果==假:
emit('Success',{'data':'16.34 GB'})
其他:
=错误
问题是:如何从客户端停止/中止循环?我试图设置一个“中止”消息,但它不起作用。换句话说,我如何使用我在代码中起草的
?以下是我的实现
服务器代码:
#!/usr/bin/env python
# make sure to use eventlet and call eventlet.monkey_patch()
import eventlet
eventlet.monkey_patch()
from flask import Flask, render_template, request, g, session, make_response, current_app, redirect, url_for
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = "secret"
# make sure to set the async_mode as 'eventlet'
socketio = SocketIO(app, async_mode='eventlet')
# our gloabal worker
workerObject = None
class Worker(object):
switch = False
unit_of_work = 0
def __init__(self, socketio):
"""
assign socketio object to emit
"""
self.socketio = socketio
self.switch = True
def do_work(self):
"""
do work and emit message
"""
while self.switch:
self.unit_of_work += 1
# must call emit from the socket io
# must specify the namespace
self.socketio.emit("update", {"msg": self.unit_of_work}, namespace="/work")
# important to use eventlet's sleep method
eventlet.sleep(1)
def stop(self):
"""
stop the loop
"""
self.switch = False
@app.route('/')
def index():
"""
renders demo.html
"""
return render_template('demo.html')
@socketio.on('connect', namespace='/work')
def connect():
"""
connect
"""
global worker
worker = Worker(socketio)
emit("re_connect", {"msg": "connected"})
@socketio.on('start', namespace='/work')
def start_work():
"""
trigger background thread
"""
emit("update", {"msg": "starting worker"})
# notice that the method is not called - don't put braces after method name
socketio.start_background_task(target=worker.do_work)
@socketio.on('stop', namespace='/work')
def stop_work():
"""
trigger background thread
"""
worker.stop()
emit("update", {"msg": "worker has been stoppped"})
if __name__ == '__main__':
"""
launch server
"""
socketio.run(app, host="0.0.0.0", port=5000, debug=True)
客户端代码:
<!DOCTYPE HTML>
<html>
<head>
<title>Demo - background worker</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var socketio = null;
var namespace = "/work"
$("input[name='connect']").on("click", function() {
console.log("connect");
socketio = io.connect(
location.protocol +
'//' +
document.domain +
':' +
location.port +
namespace
);
socketio.off().on("re_connect", function(msg) {
$(".report").append(msg.msg + "<br />");
});
});
$("input[name='start']").on("click", function() {
socketio.emit("start");
socketio.on("update", function(msg) {
$(".report").append(msg.msg + "<br />");
});
});
$("input[name='stop']").on("click", function() {
socketio.emit("stop");
socketio.on("update", function(msg) {
$(".report").append(msg.msg + "<br />");
});
});
});
</script>
</head>
<body>
<div class="main_container" >
<div class="control">
<form id="ctrl_form">
<input type="button" name="connect" value="connect" />
<input type="button" name="start" value="start" />
<input type="button" name="stop" value="stop" />
</form>
</div>
<div class="report">
...
</div>
</div>
</body>
</html>
演示-后台工作人员
$(文档).ready(函数(){
var socketio=null;
var namespace=“/work”
$(“输入[name='connect']”)。在(“单击”,函数()上){
控制台日志(“连接”);
socketio=io.connect(
location.protocol+
'//' +
document.domain+
':' +
location.port+
名称空间
);
socketio.off().on(“重新连接”,函数(msg){
$(“.report”).append(msg.msg+”
);
});
});
$(“输入[name='start']”)。在(“单击”,函数()上){
socketio.emit(“开始”);
socketio.on(“更新”,函数(msg){
$(“.report”).append(msg.msg+”
);
});
});
$(“输入[name='stop']”)。在(“单击”,函数()上){
socketio.emit(“停止”);
socketio.on(“更新”,函数(msg){
$(“.report”).append(msg.msg+”
);
});
});
});
...
这是我的实现
服务器代码:
#!/usr/bin/env python
# make sure to use eventlet and call eventlet.monkey_patch()
import eventlet
eventlet.monkey_patch()
from flask import Flask, render_template, request, g, session, make_response, current_app, redirect, url_for
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = "secret"
# make sure to set the async_mode as 'eventlet'
socketio = SocketIO(app, async_mode='eventlet')
# our gloabal worker
workerObject = None
class Worker(object):
switch = False
unit_of_work = 0
def __init__(self, socketio):
"""
assign socketio object to emit
"""
self.socketio = socketio
self.switch = True
def do_work(self):
"""
do work and emit message
"""
while self.switch:
self.unit_of_work += 1
# must call emit from the socket io
# must specify the namespace
self.socketio.emit("update", {"msg": self.unit_of_work}, namespace="/work")
# important to use eventlet's sleep method
eventlet.sleep(1)
def stop(self):
"""
stop the loop
"""
self.switch = False
@app.route('/')
def index():
"""
renders demo.html
"""
return render_template('demo.html')
@socketio.on('connect', namespace='/work')
def connect():
"""
connect
"""
global worker
worker = Worker(socketio)
emit("re_connect", {"msg": "connected"})
@socketio.on('start', namespace='/work')
def start_work():
"""
trigger background thread
"""
emit("update", {"msg": "starting worker"})
# notice that the method is not called - don't put braces after method name
socketio.start_background_task(target=worker.do_work)
@socketio.on('stop', namespace='/work')
def stop_work():
"""
trigger background thread
"""
worker.stop()
emit("update", {"msg": "worker has been stoppped"})
if __name__ == '__main__':
"""
launch server
"""
socketio.run(app, host="0.0.0.0", port=5000, debug=True)
客户端代码:
<!DOCTYPE HTML>
<html>
<head>
<title>Demo - background worker</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var socketio = null;
var namespace = "/work"
$("input[name='connect']").on("click", function() {
console.log("connect");
socketio = io.connect(
location.protocol +
'//' +
document.domain +
':' +
location.port +
namespace
);
socketio.off().on("re_connect", function(msg) {
$(".report").append(msg.msg + "<br />");
});
});
$("input[name='start']").on("click", function() {
socketio.emit("start");
socketio.on("update", function(msg) {
$(".report").append(msg.msg + "<br />");
});
});
$("input[name='stop']").on("click", function() {
socketio.emit("stop");
socketio.on("update", function(msg) {
$(".report").append(msg.msg + "<br />");
});
});
});
</script>
</head>
<body>
<div class="main_container" >
<div class="control">
<form id="ctrl_form">
<input type="button" name="connect" value="connect" />
<input type="button" name="start" value="start" />
<input type="button" name="stop" value="stop" />
</form>
</div>
<div class="report">
...
</div>
</div>
</body>
</html>
演示-后台工作人员
$(文档).ready(函数(){
var socketio=null;
var namespace=“/work”
$(“输入[name='connect']”)。在(“单击”,函数()上){
控制台日志(“连接”);
socketio=io.connect(
location.protocol+
'//' +
document.domain+
':' +
location.port+
名称空间
);
socketio.off().on(“重新连接”,函数(msg){
$(“.report”).append(msg.msg+”
);
});
});
$(“输入[name='start']”)。在(“单击”,函数()上){
socketio.emit(“开始”);
socketio.on(“更新”,函数(msg){
$(“.report”).append(msg.msg+”
);
});
});
$(“输入[name='stop']”)。在(“单击”,函数()上){
socketio.emit(“停止”);
socketio.on(“更新”,函数(msg){
$(“.report”).append(msg.msg+”
);
});
});
});
...
这方面运气好吗?我在寻找几乎相同的东西;)。我面临着同样的问题(需要能够中断向客户机发送消息的while循环;并且需要通过另一个套接字调用来中断它)。本例使用一个后台线程来运行这样的循环。因此,使用多线程可能是一个解决方案。这方面运气好吗?我在寻找几乎相同的东西;)。我面临着同样的问题(需要能够中断向客户机发送消息的while循环;并且需要通过另一个套接字调用来中断它)。本例使用一个后台线程来运行这样的循环。因此,使用多个线程可能是一个解决方案。您好@VilleLipponen在我调用stop方法后是否可以继续该线程?@bumbumpaw,我知道这是一年后的事,但如果您想继续,只需创建另一个类函数,在该函数中,您可以将开关设置为True。然后你可以创建另一个事件,或者只是在开始
中调用它。嗨@VilleLipponen在我调用stop方法之后,是否可以继续线程?@bumbumpaw,我知道这是一年后的事情,但是如果你想继续,只需创建另一个类函数,在这里你可以将开关
设置为True。然后,您可以创建另一个事件,或者在开始中调用它。