我为 Rhythmbox 创建了一个小型网络界面,后端使用MPRIS D-Bus界面与播放器进行交互。方法和属性工作正常,但我无法获得信号部分(需要运行循环)以按照我希望的方式运行。
我的想法是我有一个可以连接到TCP的守护进程,它使用Server-Sent Events格式发送事件。问题是连接的处理非常奇怪,客户端立即得到一个连接但是守护进程中生成的客户端套接字经常会被处理很多,如果它完全被处理的话。
这是守护进程的代码:
#!/usr/bin/env python
local_port = 9001
import socket
import thread
import sys
import os
import json
import subprocess
import shlex
import dbus
import dbus.mainloop.glib
import glib
import threading
def dbus_thread(lock, client_connections):
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
dbus.mainloop.glib.threads_init()
bus = dbus.SessionBus()
player_path = "org.mpris.MediaPlayer2.Player"
player_proxy = bus.get_object ("org.gnome.Rhythmbox3", "/org/mpris/MediaPlayer2")
player = dbus.Interface(player_proxy, player_path)
def sendToClients(message):
lock.acquire()
try:
for client_connection in client_connections:
socket, addr = client_connection
print "Sending message to " + str(addr) + "..."
try:
socket.sendall(message)
except:
print "Client dropped:", addr
client_connections.remove(client_connection)
finally:
lock.release()
def handleSeeked(position):
print "Seeked event:", position
sendToClients("event: Seeked\ndata: { 'position:' " + str(position) + " }\n\n")
player.connect_to_signal("Seeked", handleSeeked)
glib.MainLoop().run()
if __name__ == '__main__':
print "Daemon PID:", os.getpid()
server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
server.bind(('localhost', local_port))
server.listen(10)
print "Server listening on:", server.getsockname()
lock = threading.Lock()
client_connections = [];
thread.start_new_thread(dbus_thread, (lock, client_connections))
while True:
print "Waiting for client connection..."
client_connection = server.accept()
print "Client connected:", client_connection[1]
sys.stdout.flush()
lock.acquire()
try:
client_connections.append(client_connection)
finally:
lock.release()
基本程序是:
该行
client_connection = server.accept()
执行得很好,从客户端获得连接判断,但是之后的行只是在很久之后才会发生:
print "Client connected:", client_connection[1]
也许这是D-Bus线程以某种方式干扰,我不知道。关于如何解决这个问题的任何建议都将不胜感激。