28 may. 2012

Tutorial de ZeroMQ con Python. Parte 3.

Tomando como base el artículo de ZeroMQ parte 1, se puede crear varios servidores (como cluster de aplicación).

Está vez se crea 3 scripts servidores, pueden estar en el mismo equipo o en equipos diferentes. Lo único que cambie en cada scripts es el puerto donde escucha para el servicio.

En el cliente, se crean 3 sockets con los puertos donde escucha los 3 servidores.

La idea es pasar un mensaje por parte del cliente, los servidores los recibe y los envía de vuelta al cliente.

El código del script del lado del cliente es la siguiente:
#!/usr/bin/env python #importar zeromq import zmq #Se crea una instancia del contexto context = zmq.Context() #Se crea el socket con parametro peticion (REQ) socket = context.socket(zmq.REQ) #Se crean 3 sockets con la IP y los 3 puertos donde escucha #los 3 servidores. socket.connect("tcp://127.0.0.1:5000") socket.connect("tcp://127.0.0.1:6000") socket.connect("tcp://127.0.0.1:7000") #Se crea un ciclo de 100 repeticiones for i in range(100):     #Se crea el string del mensaje     mensaje = "mensaje %s" % i     #Se envia el mensaje     socket.send(mensaje)     #Se muestra en pantalla el mensaje enviado     print "Enviando", mensaje     #Se recibe el mensaje de vuelta     msg_in = socket.recv()
Los scripts de los servidores se muestra a continuación:
Servidor 1:
 
#!/usr/bin/env python

#Se importa zeroMQ
import zmq
#Se crea la instancia del contexto
context = zmq.Context()
#Se crea el socket pasandole como parametro respuesta (REP)
socket = context.socket(zmq.REP)
#Se asocia el socket a la IP y el puerto
socket.bind("tcp://127.0.0.1:5000")

#Se crea un ciclo
while True:
    #Se recibe el mensaje
    mensaje = socket.recv()
    #Se muestra en pantalla el mensaje recibido
    print "Recibiendo", mensaje
    #Se envia el mensaje de regreso al cliente
    socket.send(mensaje)
 
Servidor 2:
#!/usr/bin/env python

#Se importa zeroMQ
import zmq
#Se crea la instancia del contexto
context = zmq.Context()
#Se crea el socket pasandole como parametro respuesta (REP)
socket = context.socket(zmq.REP)
#Se asocia el socket a la IP y el puerto
socket.bind("tcp://127.0.0.1:6000")

#Se crea un ciclo
while True:
    #Se recibe el mensaje
    mensaje = socket.recv()
    #Se muestra en pantalla el mensaje recibido
    print "Recibiendo", mensaje
    #Se envia el mensaje de regreso al cliente
    socket.send(mensaje)
Servidor 3:
#!/usr/bin/env python

#Se importa zeroMQ
import zmq
#Se crea la instancia del contexto
context = zmq.Context()
#Se crea el socket pasandole como parametro respuesta (REP)
socket = context.socket(zmq.REP)
#Se asocia el socket a la IP y el puerto
socket.bind("tcp://127.0.0.1:7000")

#Se crea un ciclo
while True:
    #Se recibe el mensaje
    mensaje = socket.recv()
    #Se muestra en pantalla el mensaje recibido
    print "Recibiendo", mensaje
    #Se envia el mensaje de regreso al cliente
    socket.send(mensaje)

A continuación se inicia los 3 servidores y luego el cliente: En la siguiente figura se muestra los envíos realizados por el cliente:
 
Se muestra a continuación las figuras de los 3 servidores:
 
Servidor 1:
 
Servidor 2:

servidor 3:
 
 
Al ver las 3 figuras de los servidores se nota como se distribuye de forma equitativa 
la recepción de los mensajes.
 
Luego se puede complicar algo más este esquema agregando una cola entre los clientes 
y los servidores. 

27 may. 2012

Tutorial de ZeroMQ con Python. Parte 2.

Continuando con los artículos sobre ZeroMQ, en esta ocasión se muestra el uso del patrón de mensaje PAR (comunicación entre compañeros exclusivamente).

Los artículos se basan en el artículo de Nicholas Piël, una Introducción a ZeroMQ.

Socket par son muy similares a los sockets regulares. La comunicación es bidireccional, no hay un específico estado almacenado dentro del socket y solamente se puede conectar con un compañero.

La figura representa la estructura de sockets pares, el servidor escucha en un puerto seguro y un cliente se conecta a el. Las líneas rojas muestran el flujo de los mensajes, en este patrón ambos extremos usan el patrón par, y los mensajes fluyen de manera bidireccional.


Se muestra a continuación el código del servidor:
#!/usr/bin/env python #Importar zmq import zmq #Se crea la instancia del contexto context = zmq.Context() #Se crea el socket del tipo PAR socket = context.socket(zmq.PAIR) #Se asocia a una IP y puerto donde escucha el servidor. socket.bind("tcp://127.0.0.1:5555") #Se crea un ciclo. while True:     #Se recibe un mensaje del cliente     mensaje = socket.recv()     #Se muestra en pantalla     print "Recivo", mensaje     #Se envia de vuelta el mensaje     socket.send(mensaje)
El código del cliente es el siguiente:
#!/usr/bin/env python
#Se importa zmq
import zmq
#Se crea la instancia del contexto
context = zmq.Context()
#Se crea el socket con argumento del tipo de mensaje Par.
socket = context.socket(zmq.PAIR)
#Se conecta al servidor dado la IP y puerto.
socket.connect("tcp://127.0.0.1:5555")
#Se crea un cilo de 100 repeticiones.
for i in range(100):
    #Se define el mensaje a pasar
    mensaje = "mensaje %s" % i
    #Se pasa el mensaje al servidor
    socket.send(mensaje)
    #Se presenta en pantalla el mensaje
    print "Enviando", mensaje
    #Se recibe el mensaje de vuelta
    msg_in = socket.recv()
    #Se presenta en pantalla el mensaje de vuelta
    print "Recibido:", msg_in
El resultado del lado del servidor se muestra en la siguiente figura:


El resultado del lado del cliente se muestra en la siguiente figura:


Al intentar ejecutar 2 clientes al mismo tiempo el servidor termina con un mensaje de error por que sólo maneja una comunicación bidireccional con un sólo compañero.

26 may. 2012

Tutorial de ZeroMQ con python . Parte 1.

ZeroMQ es una librería de mensajes, permite crear complejos sistemas de comunicación con poco esfuerzo (sistemas de cola).

ZeroMQ es más rápido que otros sistemas de mensajes basados en el protocolo AMQP.

En este artículo se explicará un uso sencillo de zeroMQ al estilo cliente y servidor. Se usará el puerto 5000 para la comunicación entre el cliente y servidor. En el cliente se genera de forma aleatoria 2 números que se le pasan al servidor que sacará una cuenta y devuelve el resultado al cliente quien muestra el resultado en pantalla. La generación de números se realiza 1000 veces, luego le pasa al servidor la letra q la cual es la señal para terminar el servidor.


Para instalar zeroMQ para python se tiene que instalar python-zmq y/o python3-zmq para python3:
#apt-get install python3-zmq python-zmq


Servidor: El código del servidor es el siguiente:
 #!/usr/bin/env python
#Se importa zeromq
import zmq
#Se crea la instancia del contexto de zmq.
context = zmq.Context()
#Se define el socket con parámetro respuesta REP.
socket = context.socket(zmq.REP)
#Se asocia la dirección IP y el puerto donde el servidor escucha las peticiones.
socket.bind("tcp://127.0.0.1:5000")
#Se define un contados
c = 1
#Se genera un ciclo que sólo finaliza si se recibe la letra q.
while True:
    #Se recibe los mensajes.
    msg = socket.recv()
    #Se consulta si la longitud del mensaje es 1 y es la letra q se termina el ciclo
    if len(msg) == 1 and msg == "q":
        break
    #Se separa los datos que viene en un string separados por :
    datos = msg.split(":")
    #se realiza una suma con los datos recibidos.
    resultado = int(datos[0]) + int(datos[1])
    #Se muestra en pantalla el resultado
    print "Iteracion: %s ,He recibido: %s, el resultado es: %s "  %(c,msg,resultado)
    #Se envía el resultado al cliente
    socket.send(str(resultado))
    #Se incrementa el contador.
    c += 1

 
El código del cliente es el siguiente:
#!/usr/bin/env python #Se importa zeromq y random import zmq import random
#Se crea la instancia del contexto context = zmq.Context()
#Se crea el socket y se para el argumento de petición REQ socket = context.socket(zmq.REQ)
#Se coencta a la IP y puerto donde escucha el servidor socket.connect("tcp://127.0.0.1:5000")
#Se genera un ciclo de 1000 repeticiones for i in range(1000):
    #Se crea el string con el mensaje, se pasa 2 aargumentos aleatorios     msg = "%s:%s" %(random.randint(1, 1000),random.randint(1, 1000))
    #Se envia el mensaje al servidor     socket.send(msg)
    #Se recibe el mensaje del servidor     msg_in = socket.recv()
    #Se muestra en patalla los datos y el resultado     print "Iteracion: %s, Enviado: %s, Recibido: %s" %(i,msg,msg_in)
    #Si se llea a la iteración 999 se envía la letra q para finalizar     if i ==  999: socket.send("q")
El resultado del lado del cliente y del servidor es el siguiente:

La figura muestra la ejecución del script servidor:
La figura muestra la ejecución del script cliente: