通过tcp连接到dbus

Gau*_*tam 21 python dbus

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

<listen>tcp:host=localhost,port=12434</listen>
Run Code Online (Sandbox Code Playgroud)

这是我的计划:

    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()
Run Code Online (Sandbox Code Playgroud)

这是我尝试执行它时得到的结果

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
Run Code Online (Sandbox Code Playgroud)

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

更新:

好的,这是我添加的交易

<listen>tcp:host=192.168.1.7,port=12434</listen>
Run Code Online (Sandbox Code Playgroud)

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

Pulseaudio Configured For Per-user Sessions Saned Disabled;edit/etc/default/saned
Run Code Online (Sandbox Code Playgroud)

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

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

eva*_*low 32

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

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

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

    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加一行(<listen>标签正下方很好),说:

    <auth>ANONYMOUS</auth>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在这些下面添加另一行说:

    <allow_anonymous/>
    
    Run Code Online (Sandbox Code Playgroud)

<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/>
Run Code Online (Sandbox Code Playgroud)

完成这三件事后,您应该能够远程连接到会话总线.以下是在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
Run Code Online (Sandbox Code Playgroud)

即使您要发送到的总线实际上是远程计算机的系统总线,只要该设置与目标上的TCP <listen>标记匹配/etc/dbus-1/system.conf,这也可以工作.(感谢Martin Vidner的提示.直到我偶然发现他对这个问题的回答,我才认为dbus-send支持远程操作.)

UPDATE:如果您在使用systemd(和要访问的系统总线),你可能还需要添加一行说ListenStream=55557/lib/systemd/system/dbus.socket,像这样:

[Socket]
ListenStream=/var/run/dbus/system_bus_socket
ListenStream=55557  # <-- Add this line
Run Code Online (Sandbox Code Playgroud)

UPDATE2:感谢@altagir用于指出最近d-Bus的版本将使AppArmor配置在系统中是可用的中介,所以您可能还需要添加<apparmor mode="disabled"/>session.conf/ system.conf这些指令来工作.

  • @TusharVazirani:您可以使用`DBUS_SESSION_BUS_ADDRESS`环境变量来指定远程目标,即使用类似`DBUS_SESSION_BUS_ADDRESS = tcp:host = 192.168.1.17,bind =*,port = 55556,family = ipv4 ./my_python_app运行它.py`.(注意:正如我的回答中所提到的,即使你连接的总线实际上是远程机器的_system_总线 - 只要它的`system.conf`配置为允许通过TCP连接.) (2认同)

alt*_*gir 7

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

<apparmor mode="disabled"/>
Run Code Online (Sandbox Code Playgroud)

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

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

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

注意:dbus <1.6.12无法识别禁用标志,因此您需要根据systen包装不同版本的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")
Run Code Online (Sandbox Code Playgroud)