Hola, se me presenta un difÃcil problema (al menos para mÃ):
Estoy haciendo una librerÃa SIP en Ruby y no sé cómo implementar una
parte
fundamental del propio SIP:
-
Debe haber un proceso servidor corriendo permanentemente y escuchando
en el
puerto UDP 5060. Cada vez que recibe datos creará un Thread y esas cosas
(esto ya lo veo complejo pero al menos creo que con paciencia puedo
lograrlo).
-
Cuando es mi aplicación la que lanza un mensaje SIP éste debe salir
también
por el puerto UDP 5060. Pero claro, todo me indica que este proceso
cliente
es un proceso Ruby distinto al del servidor que escucha. Es más, mi
objetivo
es, por ejemplo, poder hacer en RoR una web vitaminada de Ajax que
permita un
chat SIP, y obviamente cada envÃo de mensaje desde la web constituirÃa
un
nuevo proceso SIP.
El problema es que la única forma que he visto para elegir el puerto
origen en
una comunicación UDP es haciendo un bind:
require ‘socket’
socket.bind(‘X.X.X.X’, 5060)
socket.connect(remote_address, port)
socket.send(“blablabla”,0)
Pero claro, se supone que el bind lo hará la parte servidora (que está
permanentemente escuchando).¿Cómo hago que otro proceso Ruby “cliente”
use
ese mismo socket? ¿hay alguna forma de comunicar dos procesos Ruby
independientes y compartir variables y objetos?
¿Alguna otra idea sobre cómo se suelen afrontar estas cosas? la verdad
es que
es la primera vez que intento programar algo con sockets y tal y puede
que
esté planteando fatal la solución.
Gracias por cualquier consejo.
El Domingo, 28 de Octubre de 2007, Iñaki Baz C. escribió:
Pero claro, se supone que el bind lo hará la parte servidora (que está
permanentemente escuchando).¿Cómo hago que otro proceso Ruby “cliente” use
ese mismo socket? ¿hay alguna forma de comunicar dos procesos Ruby
independientes y compartir variables y objetos?
Se me está ocurriendo que puedo separa la aplicación en dos partes:
- Un proceso “transporte” que se encarga de recibir y enviar paquetes
UDP por
el puerto 5060.
- Un proceso “usuario” que envÃa y recibe mensajes al proceso
“transporte” vÃa
socket UNIX.
Es la única forma que se me ocurre para enviar y recibir por el mismo
puerto
UDP.
No está del todo claro lo que querés, pero …
El bind, como bien decÃs, sólo puede estar en el servidor. Cada puerto
puede
ser escuchado sólo una vez al mismo tiempo. Si intentás volver a hacer
“listen” sobre el mismo puerto por otro proceso, da un error. Eso no
implica
que no puedas hacer “connect” hacia otro servidor desde ese mismo Thread
con
el mismo número de puerto.
El cliente no hace bind, hace “connect” a un puerto. Si el cliente tiene
que
“escuchar”, debe convertirse en un “servidor” y hacer “listen” en el
puerto
con otro socket.
Este seria el servidor …
require ‘socket’
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2300, ‘localhost’ )
socket.bind( sockaddr )
socket.listen( 5 )
client, client_sockaddr = socket.accept
puts “The client said, ‘#{client.readline.chomp}’”
client.puts “Hello from script one!”
socket.close
Este seria el cliente.
require ‘socket’
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_DGRAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2300, ‘elhost’ )
socket.connect( sockaddr )
socket.write( “Desde el cliente!!!” )
El dÃa 27/10/07, Iñaki Baz C. [email protected] escribió:
El Lunes, 29 de Octubre de 2007, Silvio Q. escribió:
Este seria el servidor …
Este seria el cliente.
require ‘socket’
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_DGRAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2300, ‘elhost’ )
socket.connect( sockaddr )
Gracias por toda la info. Estoy tratando de documentarme más sobre
sockets y
tal. Replanteré mejor la pregunta cuando lo tenga un poco más claro.
Muchas gracias.