不断运行的Python脚本,通过终端调用函数
我有个小问题,其实我都不太确定这是否可能 :3
我有一个Python脚本,这是一个网络脚本,它会连接到一个服务器,并保持连接,直到我手动断开或者服务器把我踢掉(通常不应该发生这种情况)。这个脚本会不断接收数据,还会执行其他任务。
我想知道在脚本运行的时候,是否可以从脚本内部触发某些功能?比如说,当脚本在运行时,如果我突然想要发送一些数据到服务器,我能不能直接输入这些数据,然后把它发送给处理这部分的函数?
我不太确定这是否可行,因为我从来没有尝试过,也没见过有人这样做。如果有帮助的话,我是在Ubuntu Linux上通过终端运行这个脚本的。
5 个回答
1
看看这个 gevent:
gevent 是一个基于协程的 Python 网络库,它使用 greenlet 来提供一个高级的同步接口,这个接口是在 libevent 事件循环之上的。
还有 gevent.socket。
1
Jacek Konieczny的解决方案很好也很简单。如果你想要更灵活的消息传递方式,可以考虑一下ZeroMQ。这个工具能让你轻松创建各种消息传递的解决方案,围绕你的主程序进行开发。使用一个线程,你的主程序大概会是这样的:
#!/usr/bin/env python
import zmq
from time import sleep
CTX = zmq.Context()
incoming = CTX.socket(zmq.PULL)
incoming.bind("tcp://127.0.0.1:3000")
outgoing = CTX.socket(zmq.PUB)
outgoing.bind("tcp://127.0.0.1:3001")
# Poller for the incoming messages
poller = zmq.Poller()
poller.register(incoming, zmq.POLLIN)
def main():
while True:
# Do things on the network
print("[Did things on the network]")
# Send messages if you want
outgoing.send("Important message")
# Poll for incoming messages
socks = dict(poller.poll(zmq.NOBLOCK))
if incoming in socks and socks[incoming] == zmq.POLLIN:
message = incoming.recv()
# Handle message
print("[Handled message '%s']" % message)
sleep(1) # Only for this dummy program
if __name__ == "__main__":
main()
接下来,你需要写一个客户端(可以用任何支持ZeroMQ的编程语言),这个客户端会从主程序中推送和订阅消息。下面是一个推送者的例子:
#!/usr/bin/env python
import zmq
CTX = zmq.Context()
pusher = CTX.socket(zmq.PUSH)
pusher.connect("tcp://127.0.0.1:3000")
def main():
pusher.send("Message to main program")
if __name__ == "__main__":
main()
还有一个订阅者的例子:
#!/usr/bin/env python
import zmq
CTX = zmq.Context()
subscriber = CTX.socket(zmq.SUB)
subscriber.connect("tcp://127.0.0.1:3001")
subscriber.setsockopt(zmq.SUBSCRIBE, "")
def main():
while True:
msg = subscriber.recv()
print("[Received message] %s" % msg)
if __name__ == "__main__":
main()
听起来你可能想把推送者和订阅者的程序合并成一个。如果你决定使用ZeroMQ,可以看看这个很棒的用户指南。
当然,你也可以在多个线程或进程中使用ZeroMQ(只要注意不要在不同线程之间共享单独的ZeroMQ套接字)。