在单独的线程中运行 SimpleXMLRPCServer 并关闭

发布于 2024-07-13 05:34:51 字数 621 浏览 7 评论 0原文

我有一个类,我希望通过 python 中的 SimpleXMLRPCServer 进行测试。 我设置单元测试的方法是创建一个新线程,并在其中启动 SimpleXMLRPCServer。 然后我运行所有测试,最后关闭。

这是我的 ServerThread:

class ServerThread(Thread):
    running = True
    def run(self):
        self.server = #Creates and starts SimpleXMLRPCServer

        while (self.running):
            self.server.handle_request()

    def stop(self):
        self.running = False
        self.server.server_close()

问题是,如果线程已经在等待 handle_request 中的请求,那么调用 ServerThread.stop(),然后调用 Thread.stop() 和 Thread.join() 将不会导致线程正确停止。 而且由于这里似乎没有任何我可以使用的中断或超时机制,因此我不知道如何干净地关闭服务器线程。

I have a class that I wish to test via SimpleXMLRPCServer in python. The way I have my unit test set up is that I create a new thread, and start SimpleXMLRPCServer in that. Then I run all the test, and finally shut down.

This is my ServerThread:

class ServerThread(Thread):
    running = True
    def run(self):
        self.server = #Creates and starts SimpleXMLRPCServer

        while (self.running):
            self.server.handle_request()

    def stop(self):
        self.running = False
        self.server.server_close()

The problem is, that calling ServerThread.stop(), followed by Thread.stop() and Thread.join() will not cause the thread to stop properly if it's already waiting for a request in handle_request. And since there doesn't seem to be any interrupt or timeout mechanisms here that I can use, I am at a loss for how I can cleanly shut down the server thread.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天邊彩虹 2024-07-20 05:34:51

我遇到了同样的问题,经过几个小时的研究,我通过从使用我自己的 handle_request() 循环切换到 serve_forever() 来启动服务器来解决它。

serve_forever() 启动像您一样的内部循环。 这个循环可以通过调用shutdown()来停止。 停止循环后,可以使用server_close()停止服务器。

我不知道为什么这有效,而 handle_request() 循环不起作用,但它确实有效;P

这是我的代码:

from threading import Thread
from xmlrpc.server import SimpleXMLRPCServer
from pyWebService.server.service.WebServiceRequestHandler import WebServiceRquestHandler

class WebServiceServer(Thread):
    def __init__(self, ip, port):
        super(WebServiceServer, self).__init__()
        self.running = True
        self.server = SimpleXMLRPCServer((ip, port),requestHandler=WebServiceRquestHandler)
    self.server.register_introspection_functions()

    def register_function(self, function):
        self.server.register_function(function)

    def run(self):
        self.server.serve_forever()

    def stop_server(self):
        self.server.shutdown()
        self.server.server_close()

print("starting server")
webService = WebServiceServer("localhost", 8010)
webService.start()
print("stopping server")
webService.stop_server()
webService.join()
print("server stopped")

I had the same problem and after hours of research i solved it by switching from using my own handle_request() loop to serve_forever() to start the server.

serve_forever() starts an internal loop like yours. This loop can be stopped by calling shutdown(). After stopping the loop it is possible to stop the server with server_close().

I don't know why this works and the handle_request() loop don't, but it does ;P

Here is my code:

from threading import Thread
from xmlrpc.server import SimpleXMLRPCServer
from pyWebService.server.service.WebServiceRequestHandler import WebServiceRquestHandler

class WebServiceServer(Thread):
    def __init__(self, ip, port):
        super(WebServiceServer, self).__init__()
        self.running = True
        self.server = SimpleXMLRPCServer((ip, port),requestHandler=WebServiceRquestHandler)
    self.server.register_introspection_functions()

    def register_function(self, function):
        self.server.register_function(function)

    def run(self):
        self.server.serve_forever()

    def stop_server(self):
        self.server.shutdown()
        self.server.server_close()

print("starting server")
webService = WebServiceServer("localhost", 8010)
webService.start()
print("stopping server")
webService.stop_server()
webService.join()
print("server stopped")
怕倦 2024-07-20 05:34:51

两个建议。

建议一是使用单独的进程而不是单独的线程。

  • 创建一个独立的 XMLRPC 服务器程序。

  • 使用subprocess.Popen()启动它。

  • 测试完成后将其杀死。 在标准操作系统(不是 Windows)中,kill 效果很好。 然而,在 Windows 中,没有简单的终止功能,但有一些方法可以实现这一点。

另一个建议是在 XMLRPC 服务器中添加一个导致服务器自毁的功能。 您定义一个函数来调用 sys.exit() 或 os.abort() 或引发类似的异常来停止进程。

Two suggestions.

Suggestion One is to use a separate process instead of a separate thread.

  • Create a stand-alone XMLRPC server program.

  • Start it with subprocess.Popen().

  • Kill it when the test is done. In standard OS's (not Windows) the kill works nicely. In Windows, however, there's no trivial kill function, but there are recipes for this.

The other suggestion is to have a function in your XMLRPC server which causes server self-destruction. You define a function that calls sys.exit() or os.abort() or raises a similar exception that will stop the process.

他不在意 2024-07-20 05:34:51

这是我的方式。 发送 SIGTERM 给自己。 (对我有用)

服务器代码

import os
import signal
import xmlrpc.server

server = xmlrpc.server.SimpleXMLRPCServer(("0.0.0.0", 8000))
server.register_function(lambda: os.kill(os.getpid(), signal.SIGTERM), 'quit')
server.serve_forever()

客户端代码

import xmlrpc.client

c = xmlrpc.client.ServerProxy("http://localhost:8000")
try:
    c.quit()
except ConnectionRefusedError:
    pass

This is my way. send SIGTERM to self. (Works for me)

Server code

import os
import signal
import xmlrpc.server

server = xmlrpc.server.SimpleXMLRPCServer(("0.0.0.0", 8000))
server.register_function(lambda: os.kill(os.getpid(), signal.SIGTERM), 'quit')
server.serve_forever()

Client code

import xmlrpc.client

c = xmlrpc.client.ServerProxy("http://localhost:8000")
try:
    c.quit()
except ConnectionRefusedError:
    pass
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文