运行使用 twind 守护进程的基于非 Twisted 的 Python 脚本

发布于 2024-12-03 21:39:24 字数 1606 浏览 1 评论 0原文

我正在编写一个由服务器(使用 Twisted)和客户端(不使用 Twisted)组成的 Python 程序

服务器部分是使用 Twisted 和 Twisted 的 应用程序框架 并通过 Twistd 启动以进行守护进程。

在不同服务器上运行的客户端是一个简单的 Python 脚本,没有任何 Twisted 的东西(也没有应用程序框架特定的东西)。它也应该作为守护进程运行。仅供参考,这是来源:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import sys
import time
import syslog

SERVER_IP = '127.0.0.1' 
SERVER_PORT = 43278 
BEAT_PERIOD = 1

class HeartbeatClient:
    '''
    A Client sending heartbeats to a monitoring server.
    '''
    def __init__(self, server_ip, port, beat_period):
        syslog.syslog( ('Sending heartbeat to IP %s , port %d' +
                        '\n press Ctrl-C to stop\n') 
                        % (SERVER_IP, SERVER_PORT))

    def run(self):
        while True:
            hbSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            hbSocket.sendto('PyHB', (SERVER_IP, SERVER_PORT))
            if __debug__: 
                print 'Time: %s' % time.ctime()
            time.sleep(BEAT_PERIOD)

if __name__ == '__main__':
    hbc = HeartbeatClient() 
    hbc.run()

现在我想知道是否也可以使用 Twistd 对客户端进行守护进程?因此,我会从客户端创建一个 Twisted-Application。但我看到的所有关于 Twisted 应用程序的示例都实现了一些 Twisted 互联网服务器内容(例如我的例子中的 internet.UDPServer...),但我的客户端不使用这些内容。

那么是否可以使用 Twistd 将我的客户端作为守护进程启动,我需要进行哪些更改?我应该重写客户端以充分利用 Twisted 吗?如果是,是否有类似的示例如何编写基于 Twisted 的网络客户端?

或者我是否必须为客户端使用不同的守护进程库?有一个很好的库,但我试图保持一致并使用客户端和服务器具有相同的守护进程机制。

I'm writing a Python program consisting of a server (using Twisted) and a client (without Twisted)

The server part is implemented using Twisted and Twisted's application framework and launched with Twistd to be daemonized.

The client which runs on a different server is a simple Python script without any Twisted stuff (and no application framework specific stuff). It should also be run as a Daemon. FYI, this is the source:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import sys
import time
import syslog

SERVER_IP = '127.0.0.1' 
SERVER_PORT = 43278 
BEAT_PERIOD = 1

class HeartbeatClient:
    '''
    A Client sending heartbeats to a monitoring server.
    '''
    def __init__(self, server_ip, port, beat_period):
        syslog.syslog( ('Sending heartbeat to IP %s , port %d' +
                        '\n press Ctrl-C to stop\n') 
                        % (SERVER_IP, SERVER_PORT))

    def run(self):
        while True:
            hbSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            hbSocket.sendto('PyHB', (SERVER_IP, SERVER_PORT))
            if __debug__: 
                print 'Time: %s' % time.ctime()
            time.sleep(BEAT_PERIOD)

if __name__ == '__main__':
    hbc = HeartbeatClient() 
    hbc.run()

Now I wonder if I can daemonize the client also with Twistd? Therefore I would have create an Twisted-Application out of the client. But all examples I saw concerning Twisted applications where implementing some Twisted internet-server stuff (like in my case internet.UDPServer...), which my client does not use.

So is it possible to use Twistd to launch my client as a daemon, and what changes do I have to make? Should I rewrite the client to take full use of Twisted? If yes, are there any similar examples out there how to write a Twisted based network client?

Or do I have to use a different daemonize library for the client? There is a good library for that, but I'm trying to be consistent and use the same daemonizing mechanism for client and server.

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

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

发布评论

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

评论(1

谁人与我共长歌 2024-12-10 21:39:24

使用 Twisted,作为 tac 文件,您的 HeartbeatClient 将如下所示:

from twisted.application.service import Application, Service
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from twisted.internet.protocol import DatagramProtocol

class HeartbeatClient(Service):
    def startService(self):
        self._call = LoopingCall(self._heartbeat)
        self._call.start(BEAT_PERIOD)

    def stopService(self):
        self._call.stop()

    def _heartbeat(self):
        port = reactor.listenUDP(0, DatagramProtocol())
        port.write('PyHB', (SERVER_IP, SERVER_PORT))
        port.stopListening()

application = Application("PyHB")
HeartbeatClient().setServiceParent(application)

请注意 reactor.listenUDP 的使用,即使您只发送 UDP 数据报,而不是接收任何。 UDP实际上没有客户端和服务器的概念,它只有开放的端口。所有UDP端口都可以发送和接收数据报。这就是为什么只有 reactor.listenUDP,而不是 reactor.connectUDP

除此之外,LoopingCall 为您提供所需的循环,并将代码放入自定义 Service 子类中,让您可以在适当的时间启动和停止循环。

With Twisted, as a tac file, your HeartbeatClient would look something like this:

from twisted.application.service import Application, Service
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from twisted.internet.protocol import DatagramProtocol

class HeartbeatClient(Service):
    def startService(self):
        self._call = LoopingCall(self._heartbeat)
        self._call.start(BEAT_PERIOD)

    def stopService(self):
        self._call.stop()

    def _heartbeat(self):
        port = reactor.listenUDP(0, DatagramProtocol())
        port.write('PyHB', (SERVER_IP, SERVER_PORT))
        port.stopListening()

application = Application("PyHB")
HeartbeatClient().setServiceParent(application)

Note the use of reactor.listenUDP, even though you're only sending UDP datagrams, not receiving any. UDP doesn't really have the concept of clients and servers, it only has open ports. All UDP ports can send and receive datagrams. That's why there's only reactor.listenUDP, not reactor.connectUDP.

Aside from that, LoopingCall gives you the loop you want, and putting the code into a custom Service subclass lets you start and stop the loop at the appropriate times.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文