Subscriptor de eventos#

Para continuar con éste ejemplo, realizaremos modificaciones en el sirviente del ejemplo de “Hello World”.

Cambios en el sirviente#

Una de las grandes ventajas que proporciona el sistema propuesto por ZeroC Ice es que no necesitamos realizar ninguna modificación en el código del sirviente.

Cambios en el servidor#

Para subscribir nuestro sirviente al topic de nuestra elección, debemos realizar las siguientes modificaciones:

  • Añadir el soporte para utilizar el “topic manager”

  • Recuperar el proxy al mismo topic que utilizarán los publicadores.

  • Subscribir nuestro proxy a dicho topic.

Para los dos primeros cambios, podemos reutilizar lo que hemos visto en el publicador.

topic_manager_str_prx = "IceStorm/TopicManager -t:tcp -h localhost -p 10000"
topic_manager = IceStorm.TopicManagerPrx.checkedCast(
    self.communicator().stringToProxy(topic_manager_str_prx),
)

if not topic_manager:
    raise RuntimeError("Invalid TopicManager proxy")

topic_name = "PrinterTopic"
try:
    topic = topic_manager.create(topic_name)
except IceStorm.TopicExists:
    topic = topic_manager.retrieve(topic_name)

Para el último, debemos utilizar el método subscribeAndGetPublisher disponible en los topics. Éste método permite subscribir un proxy a un topic, especificando una calidad de servicio (QoS). El método devolverá un publisher específico para enviar invocaciones indirectas únicamente a éste subscriber, que en este caso ignoraremos, ya que no vamos a utilizarlo desde éste programa.

qos = {}
topic.subscribeAndGetPublisher(qos, proxy)

Tras estos cambios, cada subscriptor que lancemos se unirá al topic, por lo que cada vez que el publicador se ejecute, todas esas instancias recibirán el mensaje enviado.

Ejemplo completo#

Para ejecutar el siguiente ejemplo no es necesario ningún fichero de configuración adicional.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys

import Ice
import IceStorm

Ice.loadSlice("Printer.ice")
import Example


class ConsolePrinter(Example.Printer):
    def write(self, message, current=None):
        print(message, flush=True)


class Server(Ice.Application):
    def run(self, argv):
        broker = self.communicator()
        servant = ConsolePrinter()

        adapter = broker.createObjectAdapter("PrinterAdapter")
        proxy = adapter.addWithUUID(servant)

        print(proxy, flush=True)

        adapter.activate()

        topic_manager_str_prx = "IceStorm/TopicManager -t:tcp -h localhost -p 10000"
        topic_manager = IceStorm.TopicManagerPrx.checkedCast(
            self.communicator().stringToProxy(topic_manager_str_prx),
        )

        if not topic_manager:
            raise RuntimeError("Invalid TopicManager proxy")

        topic_name = "PrinterTopic"
        try:
            topic = topic_manager.create(topic_name)
        except IceStorm.TopicExists:
            topic = topic_manager.retrieve(topic_name)

        qos = {}
        topic.subscribeAndGetPublisher(qos, proxy)

        self.shutdownOnInterrupt()
        broker.waitForShutdown()

        return 0


if __name__ == "__main__":
    server = Server()
    sys.exit(server.main(sys.argv))