通过tcp连接到dbus

时间:2012-04-15 00:52:26

标签: python dbus

我写了一个简单的python程序来播放和暂停banshee音乐播放器。 当它在我自己的机器上工作时,我无法将其连接到连接到同一路由器(LAN)的远程计算机。 我编辑了远程机器的session.conf,添加以下行:

<listen>tcp:host=localhost,port=12434</listen>

这是我的计划:

    import dbus


    bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434")
    proxy_object=bus_obj.get_object('org.bansheeproject.Banshee',                              
    '/org/bansheeproject/Banshee/PlayerEngine')

    playerengine_iface=dbus.Interface(proxy_object,
    dbus_interface='org.bansheeproject.Banshee.PlayerEngine')

    var=0

    while (var!="3"):
        var=raw_input("\nPress\n1 to play\n2 to pause\n3 to exit\n")


            if var=="1":
                print "playing..."
                playerengine_iface.Play()

            elif var=="2":
                print "pausing"
                playerengine_iface.Pause()

这是我尝试执行时获得的

Traceback (most recent call last):
  File "dbus3.py", line 4, in <module>
    bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434")
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 125, in __new__
    bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoServer: Failed to connect to socket "localhost:12434" Connection refused

我在这里做错了什么? 我应该编辑/usr/lib/python2.7/dist-packages/dbus/bus.py

更新:

好的,这是交易 当我添加

<listen>tcp:host=192.168.1.7,port=12434</listen>

到/etc/dbus-1/session.conf,然后重启,希望它会在重启时开始监听, 它永远不会靴子。它在加载屏幕上卡住,偶尔会出现以下文字的黑屏:

Pulseaudio Configured For Per-user Sessions Saned Disabled;edit/etc/default/saned

所以,当我去ctrl + alt + f1时,将session.conf更改为原始状态并重启,它会正常启动。

那是怎么回事? 如何让dbus守护进程监听tcp连接,而不会遇到问题?

3 个答案:

答案 0 :(得分:31)

我最近需要对此进行设置,并发现诀窍是:{em>订购事项 <listen>中的session.conf元素。您应该确保首先发生TCP元素。奇怪,我知道,但事实如此,至少在我的情况下。 (如果我颠倒顺序并首先放置UNIX套接字<listen>元素,我会看到完全相同的黑屏行为。)

此外,必须预先添加TCP <listen>标记,但这还不够。要通过TCP工作进行远程D-Bus连接,您需要做三件事:

  1. 在UNIX上添加<listen>标记,类似于:

    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    
  2. 添加一行(<listen>标签正下方就可以了):

    <auth>ANONYMOUS</auth>
    
  3. 在这些下方添加另一行说明:

    <allow_anonymous/>
    
  4. <auth>中可能包含的任何其他<auth>标记外,还应添加session.conf标记。总而言之,您的session.conf应该包含如下所示的代码段:

    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    
    <auth>ANONYMOUS</auth>
    <allow_anonymous/>
    

    执行这三项操作后,您应该能够远程连接到会话总线。以下是在D-Feet中指定远程连接时的外观:

    D-Feet screen capture

    请注意,如果您还要连接到系统总线,则需要对/etc/dbus-1/system.conf进行类似的更改,但需要指定不同的 TCP端口,例如55557.(奇怪的是,在这种情况下,元素顺序似乎并不重要。)

    我在此配置中注意到的唯一奇怪行为是,运行带有sudo的桌面应用程序(例如sudo gvim)往往会产生错误或直接失败,说“没有D-BUS守护程序正在运行” 。但这是我需要这样做的事情,很少这么重要。

    如果您想使用dbus-send发送到远程计算机,则需要相应地设置DBUS_SESSION_BUS_ADDRESS,例如:

    export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=*,port=55556,family=ipv4
    

    即使您要发送到的总线实际上是远程计算机的 system 总线,只要该设置与{{1}中的TCP <listen>标记相匹配,这种方法也能正常工作在目标上。 (感谢Martin Vidner提示。在我偶然发现this question的答案之前,我不相信/etc/dbus-1/system.conf支持远程操作。)

    更新:如果您正在使用systemd(并希望访问系统总线),则可能还需要向dbus-send添加一行ListenStream=55557,例如这样:

    /lib/systemd/system/dbus.socket

    UPDATE2 :感谢@altagir指出recent versions of D-Bus将在可用的系统上启用AppArmor中介,因此您可能还需要添加{{1} } [Socket] ListenStream=/var/run/dbus/system_bus_socket ListenStream=55557 # <-- Add this line / <apparmor mode="disabled"/>,以使这些说明有效。

答案 1 :(得分:7)

自dbus 1.6.12(例如kubuntu 13.10)以来,除非添加到dbus配置文件(/etc/dbus-1/mybus.conf或界面),否则您的连接也将被拒绝需要远程访问,即system.d / my.interface.conf

<apparmor mode="disabled"/>

更新:在努力创建一个允许服务连接到自定义dbus-daemon的apparmor配置文件之后,由于DBUS中的错误,似乎连接总是被拒绝... 因此,现在我们必须禁用apparmor每当你使用tcp = ...错误修复目标为14.04

我在与Tyler Hicks的讨论bugs.launchpad.net之后在here打开了一个错误:

  

AppArmor中介代码只能检查对等标签   在UNIX域套接字上。很可能在什么时候看到错误   得到标签,然后拒绝连接。

注意: dbus&lt;无法识别禁用标志。 1.6.12,所以你需要打包不同版本的mydaemon.conf,具体取决于systen),否则如果没有apparmor,dbus-daemon将在启动时失败...我现在用在我的CMakeLists.txt中:

IF(EXISTS "/usr/sbin/apparmor_status")
  install(FILES dbus_daemon-apparmordisabled.conf RENAME dbus_daemon.conf DESTINATION /etc/dbus-1/ )
ELSE (EXISTS "/usr/sbin/apparmor_status")
   install(FILES dbus_daemon.conf DESTINATION /etc/dbus-1/ )
ENDIF(EXISTS "/usr/sbin/apparmor_status")

答案 2 :(得分:3)

另一位感谢@Shorin和另一个FYI - 我不得不做这样的事情让我的工作:

<listen>tcp:host=localhost,bind=0.0.0.0,port=55884</listen>

注意bind=0.0.0.0 - bind=*对我不起作用,我遗漏了family=ipv4部分。我在Ubuntu 12.04上。我确实在远程机器上使用netstat确认dbus正在侦听端口并从本地telnet以确认端口已打开。

netstat -plntu | grep 55884

tcp   0     0 0.0.0.0:55884    0.0.0.0:*     LISTEN    707/dbus-daemon

您必须看到类似0 0.0.0.0:55884的内容,而不是0 127.0.0.1:55884