24

我写了一个简单的 python 程序来播放和暂停女妖音乐播放器。虽然它在我自己的机器上工作,但我无法在连接到同一路由器 (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 连接,而不会遇到问题?

4

3 回答 3

39

我最近需要设置它,并发现诀窍是:顺序对于. 您应该确保 TCP 元素首先出现。奇怪,我知道,但确实如此,至少对我而言。(如果我颠倒顺序并将 UNIX 套接字元素放在首位,我会看到完全相同的黑屏行为。)<listen>session.conf<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/>
    

除了您<auth>的. 总之,您应该包含一个如下所示的代码段:<auth>session.confsession.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 屏幕截图

请注意,如果您也想连接到系统总线,您需要对 进行类似的更改/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

即使您要发送到的总线实际上是远程计算机的系统总线,只要设置与目标上的 TCP<listen>标记匹配,这仍然有效/etc/dbus-1/system.conf。(感谢Martin Vidner的提示。在我偶然发现他对这个问题的回答之前,我不相信dbus-send支持远程操作。)

更新:如果您正在使用 systemd(并且想要访问系统总线),您可能还需要添加一行ListenStream=55557to /lib/systemd/system/dbus.socket,如下所示:

[Socket]
ListenStream=/var/run/dbus/system_bus_socket
ListenStream=55557  # <-- Add this line

更新2:感谢@altagir指出最新版本的 D-Bus将在可用的系统上启用AppArmor中介,因此您可能还需要添加<apparmor mode="disabled"/>session.conf/system.conf以使这些说明正常工作。

于 2012-11-07T18:35:58.937 回答
7

从 dbus 1.6.12(例如 kubuntu 13.10)开始,您的连接也将被拒绝,除非您添加到 dbus 配置文件(/etc/dbus-1/mybus.conf或需要远程访问的接口,即 system.d/ my.接口.conf )

<apparmor mode="disabled"/>

更新:在努力创建允许服务连接到自定义 dbus-daemon 的 apparmor 配置文件之后,由于 DBUS 中的错误,似乎连接总是被拒绝......所以现在我们必须在使用 tcp= 时禁用 apparmor。 .. 针对 14.04 的错误修复

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

AppArmor 中介代码只能通过 UNIX 域套接字检查对等标签。获取标签然后拒绝连接时很可能会看到错误。

注意:dbus < 1.6.12 无法识别禁用标志,因此您需要根据系统打包不同版本的 mydaemon.conf),否则如果没有 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")
于 2013-11-15T23:04:25.350 回答
3

再次感谢@Shorin,另一个仅供参考 - 我必须做这样的事情才能让我的工作:

<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

于 2013-11-29T03:30:00.437 回答