Подключение к dbus через tcp - программирование
Подтвердить что ты не робот

Подключение к dbus через tcp

Я написал простую программу 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/python 2.7/dist-packages/dbus/bus.py

UPDATE:

ОК, вот сделка когда я добавляю

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

to/etc/dbus-1/session.conf, затем перезагрузитесь, надеясь, что он начнет прослушивание при перезагрузке, Он никогда не садится. Он застревает на экране загрузки, а иногда черный экран со следующим текстом мигает:

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

поэтому, когда я иду ctrl + alt + f1, измените session.conf на исходное состояние и перезагрузитесь, он правильно загрузится.

Что это все? Как я могу заставить dbus-демона прослушивать tcp-соединения, не сталкиваясь с проблемами?

4b9b3361

Ответ 1

Мне недавно нужно было установить это, и обнаружил, что трюк: порядок имеет значение для <listen> элементов в session.conf. Прежде всего, убедитесь, что элемент TCP встречается. Необычный, я знаю, но правда, по крайней мере, для моего дела. (Я вижу точно такое же поведение черного экрана, если я отменяю порядок и сначала помещаю элемент UNIX socket <listen>.)

Кроме того, добавление тега TCP <listen> необходимо, но недостаточно. Чтобы сделать удаленные соединения D-Bus через TCP, вам нужно сделать три вещи:

  • Добавьте тег <listen> над UNIX, похожим на это:

    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    
  • Добавьте строку (прямо под тегами <listen>), которая гласит:

    <auth>ANONYMOUS</auth>
    
  • Добавьте следующую строку ниже:

    <allow_anonymous/>
    

Тег <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-порт. (Как ни странно, порядок элемента в данном случае не имеет значения.)

Единственное странное поведение, которое я заметил в этой конфигурации, заключается в том, что запуск приложений для настольных компьютеров с 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 на целевом объекте. (Спасибо Мартин Виднер за этот отзыв. Пока я не наткнулся на его ответ на этот вопрос, t верить dbus-send поддерживаемой дистанционной работе.)

UPDATE. Если вы используете systemd, вам также может потребоваться добавить строку, обозначающую ListenStream=6668 на /lib/systemd/system/dbus.socket, например:

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

UPDATE2. Благодаря @altagir, указав, что последние версии D-Bus позволят AppArmor посредничество в системах, где оно доступно, поэтому вам может потребоваться добавить <apparmor mode="disabled"/> в session.conf/system.conf, чтобы эти инструкции работали.

Ответ 2

так как dbus 1.6.12 (например, kubuntu 13.10), ваше соединение также будет отклонено, если вы не добавите в свой конфигурационный файл dbus (либо/etc/dbus-1/mybus.conf, либо интерфейс, требующий удаленного доступа, т.е. system.d/my.interface.conf)

<apparmor mode="disabled"/>

ОБНОВЛЕНИЕ:. После попытки создать профиль apparmor, позволяющий службе подключиться к пользовательскому дембусу dbus, кажется, что соединение всегда отклоняется из-за ошибки в DBUS... Итак, пока мы ДОЛЖНЫ отключить apparmor всякий раз, когда вы используете tcp =... Исправлена ​​ошибка для 14.04

Я открыл ошибку bugs.launchpad.net после обсуждения здесь с Tyler Hicks:

Код посредничества AppArmor имеет возможность проверять метки одноранговых узлов через сокеты домена UNIX. Скорее всего, возникает ошибка, когда получение метки, а затем отказ от соединения.

Примечание: флаг отключения не распознается dbus < 1.6.12, поэтому вам нужно упаковать различные версии mydaemon.conf в зависимости от systen), иначе dbus-daemon завершится с ошибкой при запуске, если не будет apparmor... Я использовал сейчас в своем 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")

Ответ 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.