Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x python socketio和Flask:如何停止后台线程中的循环?_Python 3.x_Flask_Socket.io - Fatal编程技术网

Python 3.x python socketio和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

在我的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,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。然后,您可以创建另一个事件,或者在
开始中调用它。