2016-07-08 1 views
0

Я работаю с pydbus, и мне уже удалось использовать его для прослушивания сигналов на шине сеанса (на стороне клиента). Я хотел бы написать серверную сторону сейчас, где программа посылает сигнал каждый раз, когда действие запускается (например, когда он записывает файл в FS). На самом деле у меня нет такого примера на их GitHub. Они показывают только, как писать базовый сервер, у которого есть куча методов, которые клиент может вызвать (но это не сигналы, которые я хочу).Используйте библиотеку pydbus для отправки сигнала по шине сеанса

FYI, на стороне клиента очень проста и выглядит следующим образом:

# Subscribe to DBus dump signal 
session_bus = SessionBus() 
session_bus.subscribe(iface='my.iface', 
         signal='my_signal_name', 
         object='/my/object', 
         signal_fired=my_callback) 

# Create and run main loop 
loop = GObject.MainLoop() 
loop.run() 

Где my_callback метод вызывается каждый прослушиваемых выскакивает событий (my_signal_name в данном случае)

Thx за помощью.

ответ

0

Класс, ответственный за сигналы, находится в модуле generic. Это выглядит достаточно хорошо задокументировано:

Static signal object 

You're expected to set it as a class property:: 

    class A: 
     SomethingHappened = signal() 

Declared this way, it can be used on class instances 
to connect signal observers:: 

    a = A() 
    a.SomethingHappened.connect(func) 

and emit the signal:: 

    a.SomethingHappened() 

You may pass any parameters to the emiting function 
- they will be forwarded to all subscribed callbacks. 

Существует также example in the tutorial, который использует сигнал. Обратите внимание на последнюю строку и свойство SomeProperty. Когда свойство python SomeProperty изменяется в сеттере, сигнал испускается через self.PropertiesChanged("net.lew21.pydbus.TutorialExample", {"SomeProperty": self.SomeProperty}, []).

from pydbus.generic import signal 

class Example(object): 
    """ 
    <node> 
     <interface name='net.lew21.pydbus.TutorialExample'> 
     <method name='EchoString'> 
      <arg type='s' name='a' direction='in'/> 
      <arg type='s' name='response' direction='out'/> 
     </method> 
     <property name="SomeProperty" type="s" access="readwrite"> 
      <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/> 
     </property> 
     </interface> 
    </node> 
    """ 

    def EchoString(self, s): 
    """returns whatever is passed to it""" 
    return s 

    def __init__(self): 
    self._someProperty = "initial value" 

    @property 
    def SomeProperty(self): 
    return self._someProperty 

    @SomeProperty.setter 
    def SomeProperty(self, value): 
    self._someProperty = value 
    self.PropertiesChanged("net.lew21.pydbus.TutorialExample", {"SomeProperty": self.SomeProperty}, []) 

    PropertiesChanged = signal() 

Существует также notification_server example, где используются сигналы (но не называется).

0

Следующая программа python3/pydbus будет публиковать случайное целое число каждую секунду на сеансе D-Bus.

#!/usr/bin/env python3 
#! 
from pydbus.generic import signal 
from pydbus import SessionBus 
from gi.repository import GLib 
import random 
loop = GLib.MainLoop() 
interface_name = "org.example.project_1.server_1" 
bus = SessionBus() 


class Server_XML(object): 
    """ 
    Server_XML definition. 
    Emit/Publish a signal that is a random integer every second 
    type='i' for integer. 
    """ 
    dbus = """ 
    <node> 
     <interface name="org.example.project_1.server_1"> 
      <signal name="app_1_signal"> 
       <arg type='i'/> 
      </signal> 
     </interface> 
    </node> 
    """ 
    app_1_signal = signal() 

def repeating_timer(): 
    """Generate random integer between 0 and 100 and emit over Session D-Bus 
    return True to keep the GLib timer calling this function once a second.""" 
    random_integer = random.randint(0,100) 
    print(random_integer) 
    emit.app_1_signal(random_integer) 
    return True 


if __name__=="__main__": 
    # Setup server to emit signals over the DBus 
    emit = Server_XML() 
    bus.publish(interface_name, emit) 
    # Setup repeating timer 
    GLib.timeout_add_seconds(interval=1, function=repeating_timer) 
    # Run loop with graceful ctrl C exiting. 
    try: 
     loop.run() 
    except KeyboardInterrupt as e: 
     loop.quit() 
     print("\nExit by Control C") 

Открыть другой Linux консоль терминала и использовать утилиту gdbus, чтобы проверить, что целые числа публикуются на шину сессии. Например ...

$ gdbus monitor --session --dest org.example.project_1.server_1 
Monitoring signals from all objects owned by org.example.project_1.server_1 
The name org.example.project_1.server_1 is owned by :1.618 
/org/example/project_1/server_1: org.example.project_1.server_1.app_1_signal (36,) 
/org/example/project_1/server_1: org.example.project_1.server_1.app_1_signal (37,) 
/org/example/project_1/server_1: org.example.project_1.server_1.app_1_signal (25,) 

Следующая программа python3/pydbus клиент подписывается на случайные числа публикуется на сессии D-Bus ...

#!/usr/bin/env python3 
#! 
from pydbus.generic import signal 
from pydbus import SessionBus 
from gi.repository import GLib 
loop = GLib.MainLoop() 
dbus_filter = "/org/example/project_1/server_1" 
bus = SessionBus() 


def cb_server_signal_emission(*args): 
    """ 
    Callback on emitting signal from server 
    """ 
    print("Message: ", args) 
    print("Data: ", str(args[4][0])) 

if __name__=="__main__": 
    # Subscribe to bus to monitor for server signal emissions 
    bus.subscribe(object = dbus_filter, 
        signal_fired = cb_server_signal_emission)  
    loop.run() 

Консоль вывода из этого клиента программы будет аналогичны этому ...

$ python3 client_pydbus.py 
Message: (':1.621', '/org/example/project_1/server_1', 'org.example.project_1.server_1', 'app_1_signal', (72,)) 
Data: 72 
Message: (':1.621', '/org/example/project_1/server_1', 'org.example.project_1.server_1', 'app_1_signal', (46,)) 
Data: 46 
Message: (':1.621', '/org/example/project_1/server_1', 'org.example.project_1.server_1', 'app_1_signal', (47,)) 
Data: 47 
Смежные вопросы