Python:在等待服务器套接字连接时运行循环
我有一个液晶显示屏,用来显示我在XBMC上观看电影的时间码。我希望在没有播放内容的时候,能显示当前的日期和时间。这个液晶显示屏是通过一个运行Python的TCPSocketServer服务器来工作的,它接收来自我XBMC安装的文本信息。问题是,我必须保持一个活跃的网络连接,这样XBMC才能通过这个连接发送时间和日期,液晶显示屏才能显示出来。
我觉得最好的办法是先显示液晶显示屏所在机器的日期,然后在连接活跃时切换到“时间码视图”。
有没有什么“Python风格”的方法,可以设置一个TCPSocketServer,让它在等待连接时循环显示日期,然后在接收到数据时改变行为来处理这些数据?
非常感谢!
1 个回答
0
这里有段代码可以实现你想要的功能。它启动了一个TCP服务器,监听发送到9876端口的文本。当收到文本时,它会把这些文本发送给显示对象。同时,代码还设置了一个定时器,每秒运行一次,向显示对象发送“闲置文本”(也就是当前的时间戳)。
显示对象会接收到来自服务器的正常更新文本,以及来自第二个线程的“闲置文本”。这个对象知道自从上次收到真实文本已经过了多久,因此会显示这两种消息中的一种。
如果显示对象连接到了硬件,它可以使用 multiprocessing.RLock
或其他机制来保护自己。
祝你玩得开心!
lcdcontrol.py 源代码
import signal, SocketServer, threading, time
class Display(object):
IDLE_TIME = 5 # seconds
def __init__(self):
self.updated = None
self.write('Hello')
def _write(self, arg):
print 'DISPLAY:', arg
def write(self, arg):
"""
update display and 'last updated' timestamp
"""
self._write(arg)
self.updated = time.time()
def idle(self, arg):
"""
update display only if it's been a few seconds
"""
if time.time() - self.updated >= self.IDLE_TIME:
self._write(arg)
class DisplayHandler(SocketServer.BaseRequestHandler):
DisplayObj = None # class var
def handle(self):
text = self.request.recv(1024).strip()
print "{} wrote: {}".format(
self.client_address[0], text,
)
# send text to LCD immediately
self.DisplayObj.write(text)
def check_idle(display_obj):
"""
update display with current time if it's idle
"""
while True:
display_obj.idle(
time.strftime('time: %H:%M:%S'),
)
time.sleep(1)
def start_server(host, port):
"""
start (single threaded) server
"""
SocketServer.TCPServer(
(host, port),
DisplayHandler,
).serve_forever()
def main(host, port):
display = Display()
# store global display obj so Handler can get to it
DisplayHandler.DisplayObj = display
print 'serving on {}:{}'.format(host, port)
print 'Example: echo beer | nc localhost {}'.format(port)
print
server_t = threading.Thread(
target=start_server, args=(host, port)
)
server_t.daemon = True
server_t.start()
idle_t = threading.Thread(
target=check_idle, args=[display],
)
idle_t.daemon = True
idle_t.start()
# wait for control-C to interrupt
try:
signal.pause()
except KeyboardInterrupt:
pass
if __name__ == "__main__":
main("localhost", 9876)
示例运行
在这里,我启动了服务器,等了几秒钟,然后输入了 fortune -s | nc localhost 9876
来给我的LCD服务器发送一条简短的幸运语。
注意“闲置计时器”在 :07
停止,输出了幸运语,等了五秒钟,然后继续显示 :13
和 :14
。这个消息显示了五秒钟后又切换回闲置时间戳。
python ./lcdcontrol.py
DISPLAY: Hello
serving on localhost:9876
Example: echo beer | nc localhost 9876
DISPLAY: time: 13:08:06
DISPLAY: time: 13:08:07
127.0.0.1 wrote: Some people need a good imaginary cure for their painful imaginary ailment.
DISPLAY: Some people need a good imaginary cure for their painful imaginary ailment.
DISPLAY: time: 13:08:13
DISPLAY: time: 13:08:14
DISPLAY: time: 13:08:15
DISPLAY: time: 13:08:16