Hola Mundo con ZeroC Ice#
En este capítulo vamos a ver, tras lo aprendido en el capítulo anterior, como integrar la clase anterior en un servidor Ice y como implementar un cliente para la misma.
Interfaz#
Como comentamos, es imprescindible definir una interfaz de comunicación para que los clientes sepan qué métodos pueden invocar y qué argumentos son necesarios y cuáles esperar como valor de retorno.
module Example {
interface Printer {
void write(string message);
};
};
Servidor de Hola Mundo#
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import Ice
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.add(servant, broker.stringToIdentity("printer1"))
print(proxy, flush=True)
adapter.activate()
self.shutdownOnInterrupt()
broker.waitForShutdown()
return 0
if __name__ == "__main__":
server = Server()
sys.exit(server.main(sys.argv))
Además del sirviente, ya visto y explicado en profundidad en el apartado anterior,
haremos uso de Ice.Application
.
Esta clase es una utilidad que ofrece ZeroC ICE a los desarrolladores de aplicaciones para poder crear servidores de manera mucho más sencilla.
Desde el punto de vista del desarrollador, lo único que hay que hacer es lo siguiente:
Crear una clase que herede de
Ice.Application
.Implementar el método
run
, que acepta un argumento. El código dentro del método será el que se ejecute cuando la aplicación se ejecute en el siguiente paso.Crear un objeto de nuestra nueva clase y llamar a su método
main
, pasándole la línea de argumentos (o una variable equivalente).
Internamente, el método main
, que es heredado de la Ice.Application
,
realizará una serie de inicializaciones de ICE y finalmente llamará al método run
que hemos definido.
En nuestro ejemplo, el código realiza las 4 operaciones que cualquier servidor ICE realizara:
Inicializar y activar el adaptador de objetos.
Crear el sirviente (o sirvientes) y añadirlos al adaptador de objetos.
Configurar el modo de salida (
shutdownInInterrupt
). En este caso se realizará unshutdown
del broker de comunicación cuando se reciba una interrupción.Activar el modo de espera del broker:
waitForShutdown
.
Cliente de Hola Mundo#
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import Ice
Ice.loadSlice('Printer.ice')
import Example
class Client(Ice.Application):
def run(self, argv):
proxy = self.communicator().stringToProxy(argv[1])
printer = Example.PrinterPrx.checkedCast(proxy)
if not printer:
raise RuntimeError('Invalid proxy')
printer.write('Hello World!')
return 0
sys.exit(Client().main(sys.argv))
Para el cliente hemos vuelto a utilizar la misma Ice.Application
,
aunque en esta ocasión los pasos que realiza el método run
son algo diferentes,
al tratarse de un cliente puro:
Generamos un proxy genérico a partir del stringfied proxy que recibimos por la línea de argumentos.
Tratamos de hacer una conversión desde ese proxy genérico a un
Example.PrinterPrx
, utilizando el métodocheckedCast
.Si la conversaión falla, el método anterior devolverá un
None
, y saldremos.Si la conversión fue bien, usaremos el proxy para realizar una invocación remota al método
write
.