Foros del Web » Programación para mayores de 30 ;) » Java »

Enviar mensajes de cliente a cliente

Estas en el tema de Enviar mensajes de cliente a cliente en el foro de Java en Foros del Web. Hola de nuevo, Estoy haciendo una especie de messenger como he comentado en otros temas. La verdad que gracias a vuestra ayuda he conseguido adelantar ...
  #1 (permalink)  
Antiguo 02/05/2006, 15:16
 
Fecha de Ingreso: noviembre-2003
Ubicación: Torrelodones
Mensajes: 134
Antigüedad: 20 años, 5 meses
Puntos: 0
Enviar mensajes de cliente a cliente

Hola de nuevo,

Estoy haciendo una especie de messenger como he comentado en otros temas. La verdad que gracias a vuestra ayuda he conseguido adelantar bastante pero me queda lo mas dificil. Como envio un mensaje de un cliente a otro. El tema seria que un cliente (pepe) envia un mensaje a un amigo(juan). Ambos estan conectados al Serversocket. Entonces, pepe envia un mensaje el cual iria primero al servidor y de aqui a juan. La primera parte de enviar un mensaje al servidor la entiendo y se como se haria pero lo que no se es como se envaria el mensaje desde el servidor a otro cliente. ¿Como podria hacerlo?¿Tendria que crear tambien un ServerSocket en la parte cliente? A lo mejor estoy diciendo unas burradas inmesas(seguramente) pero es que no entiendo mucho

Muchas gracias
Un saludo
__________________
Conoce gente nueva, haz amigos, aplicaciones para moviles, juegos online,... Y todo gratis!!! :si: www.cuelate.com
  #2 (permalink)  
Antiguo 02/05/2006, 22:18
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Hola:

Una vez establecida la conexión, el sentido es bidireccional. Con el mismo socket puedes enviar mensajes en los dos sentidos, de cliente a servidor y de servidor a cliente. Si juan está conectado, el servidor puede enviarle un mensaje por el mismo socket que los recibe de él. Simplemente pídele al socket un getOutputStream() en vez de un getInputStream().

Se bueno
__________________
Apuntes Java
Wiki de Programación
  #3 (permalink)  
Antiguo 03/05/2006, 04:44
 
Fecha de Ingreso: noviembre-2003
Ubicación: Torrelodones
Mensajes: 134
Antigüedad: 20 años, 5 meses
Puntos: 0
Si pero si el mensaje lo envia pepe lo recojo en el servidor con el getInputStream(), pero como desde aqui(desde la sesion socket de pepe en el servidor) puedo averiguar cual es el socket de juan en el servidor para enviaselo con el getOutputStream().

Muchas gracias de nuevo
__________________
Conoce gente nueva, haz amigos, aplicaciones para moviles, juegos online,... Y todo gratis!!! :si: www.cuelate.com
  #4 (permalink)  
Antiguo 03/05/2006, 06:30
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Hola:
Eso depende de cómo tengas organizado tu código. Lo normal sería que el servidor guardara todos los sockets de todo el mundo y pudiera identificar cada uno de ellos, por ejemplo, con su nombre de usuario.

La clase que maneje el socket "pepe" debería tener alguna forma de decirle al servidor "envia este mensaje a juan" y el servidor se encargaría de ello.

Otra forma, quizás un poco más chapucera, pero más sencilla, es hacer un Hashtable en el que guardes los sockets, usando como clave el nombre de usuario.

hash.put ("pepe", socketdepepe);
hash.put ("juan", socketdejuan);

Esta hash puede ser un atributo estático de cualquier clase (por ejemplo, la del main, o la que actualmente tengas que guarde todos los sockets).

Al ser estatico, el socket de pepe puede hacer esto

socket = ClaseQueGuardaLosSockets.hash.get("juan");

y así obtienes el socket de juan, le envías el mensaje y listo.

En fin, posibilidades hay muchas, es cuestión de buscar la que te resulte más cómoda.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #5 (permalink)  
Antiguo 03/05/2006, 09:17
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
¿Y usar algo de más alto nivel para no tener que currárselo todo a pelo? Tipo JMS o así, o al menos RMI.

A no ser que sea una práctica para aprender sockets, claro .
  #6 (permalink)  
Antiguo 03/05/2006, 12:54
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Hola:

No sé. Yo veo mucho más complejo rmi que sockets, no el código, sino lo que lleva debajo (rmiregistry, rmic, etc). JMS es para J2EE ¿no?.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #7 (permalink)  
Antiguo 03/05/2006, 15:09
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
No se. Comparando el trabajo que lleva hacerte el montaje de sockets, socket servers, enviar datos formateados, interpretar los datos que se mandan, etc. Yo veo mucho más sencillo usar RMI. Montar un rmi registry son 3 lineas de codigo (lo puedes hacer desde tu programa) y el rmic se hace "solo" si lo automatizas... pero bueno.

Para usar JMS no necesitas usar un contenedor J2EE. Hay servidores ligeros como el OpenJMS que te lo dan, aunque si es verdad que esta dentro de los servicios que un servidor J2EE ofrece (como servlets, JSP, transaccionalidad...).

Yo lo veo más sencillo, pero quizá es por que ya los he usado.
Un saludo
  #8 (permalink)  
Antiguo 03/05/2006, 15:46
 
Fecha de Ingreso: noviembre-2003
Ubicación: Torrelodones
Mensajes: 134
Antigüedad: 20 años, 5 meses
Puntos: 0
Muchas gracias por vuestra ayuda. La verdad que es la primera vez que oigo hablar de lo del RMI pero aun asi no puedo utilizarlo puesto que es para una practica y solo puedo utilizar socket en TCP. Ya he conseguido lo de enviar mensajes de cliente a cliente aunque en ocasiones falla asi que tendre que profundizar mas en el tema
__________________
Conoce gente nueva, haz amigos, aplicaciones para moviles, juegos online,... Y todo gratis!!! :si: www.cuelate.com
  #9 (permalink)  
Antiguo 03/05/2006, 16:36
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Ya me parecía . Entonces dale caña a los sockets, que aunque luego no los uses a menudo, siempre es bueno saber lo que hay por debajo de lo que usas .
  #10 (permalink)  
Antiguo 03/05/2006, 22:02
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Hola GreenEyed:

Después de lo que comentamos sobres sockets y rmi, me dio la impresión de que nuestros únicos argumentos eran sobre facilidad de programación. Supuse que había algo más, así que me puse a mirar cuándo es mejor usar sockets y cuándo rmi según otros criterios más "serios" y no de programadores perezosos .

En http://www.chuidiang.com/chuwiki/ind...ockets_%26_rmi tienes mis conclusiones. Puedes añadir allí mismo si quieres más cosas. Echale un ojo al enlace que hay al final, que es el que más me ha aclarado (está en el idioma de Shakespeare).

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #11 (permalink)  
Antiguo 04/05/2006, 05:00
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
.

1.- La decisión de usar RMI o sockets no responde a criterios de programador perezoso, si no de no "reinventar la rueda", pero bueno, piensa lo que quieras .

2.- Con todo respeto, tus conclusiones están llenas de imprecisiones, así como el enlace que pones como referencia y más te ha aclarado. Por poner algún ejemplo, te diré que no es cierto que para usar RMI necesites instalar un SecurityManager, si no que únicamente es necesario cuando realizas ciertas acciones en tu programa, si no, no. Tampoco es cierto que sea necesario arrancar el programa rmiregistry.

3.- Tampoco he dicho yo que sea siempre más conveniente usar RMI que sockets, únicamente lo ponía como un ejemplo de algo de más alto nivel que sockets para la aplicación en concreto de la que estabamos hablando. De hecho hay motivos muy claros por los que escogería usar sockets sobre RMI en ciertos casos, pero la "complejidad" de RMI por tener que usar el rmic o tener un registro en marcha no serían ninguna de ellas.

Todo esto lo digo de buen rollete, pero únicamente quería aclarar lo que he dicho y no he dicho, y bueno, dejar claro que no estoy de acuerdo con ese análisis .

Un saludo
  #12 (permalink)  
Antiguo 04/05/2006, 05:23
Avatar de dogduck  
Fecha de Ingreso: enero-2006
Ubicación: ¿Atlantida, Hesperides, Islas afortunadas?
Mensajes: 2.231
Antigüedad: 18 años, 4 meses
Puntos: 19
chuidiang . Te lo curras , si señor . A parte de ser un forero que aporta código y soluciones ( otros solo aportamos verborrea ... ), se ve que te gusta compartir tus conocimientos.

Oye Green . ¿ Por que no colaboras con chuidiang y matizas las condiciones en que hace falta, al usar rmi, instalar un SecurityManager y cuando sí, o cuando no hace falta rmiregistry ? Ya sé que no estás obligado, pero la comunidad te lo agradeceria ...
Creo que no hay mejor crítica , que la constructiva . Un simple "no estoy de acuerdo con ese análisis" suena a pereza


Lo que me queda claro de el análisis es que el factor de BW ( ancho de banda ) y/o saturación de una red puede ser la clave de la decisión de usar sockets o algo de más nivel.
Otra factor , seria que por lo visto con RMI , no se podria usar sockets broadcast ( sockets UDP para difusion o 'toda lared' )... eso parece limitar bastante para ciertas aplicaciones de redes .

Última edición por dogduck; 04/05/2006 a las 05:28
  #13 (permalink)  
Antiguo 04/05/2006, 05:37
Avatar de pyanqn  
Fecha de Ingreso: noviembre-2005
Mensajes: 331
Antigüedad: 18 años, 5 meses
Puntos: 8
la decision de utilizar un servidor por que es? por que no haces que cada cliente realice una exploración de tu intranet (broadcast).

Yo realice algo asi, y las cosas son mas faciles, y no tienes las complicaciones de la centralizaciòn.
  #14 (permalink)  
Antiguo 04/05/2006, 05:50
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Jejeje. Y dale con la pereza. A mi lo que me suena a pereza es hacer un análisis incompleto y de ahí sacar conclusiones, o pedirles a los demás que hagan el análisis por tí, pero eso soy yo.

Y si, RMI no esta pensado para hacer "broadcast" puesto que está dirigido a llamadas punto a punto y para ese tipo de aplicaciones no sirve. Pero como en este caso no se usa broadcast (de red), de ahí la sugerencia. No son tan habituales las aplicaciones que usen broadcast, excepto en aplicaciones para LAN, pero para estas RMI no vale.

El ancho de banda no lo veo yo como algo decisivo excepto en casos muy extremos, pero ya digo que es una opinión.
  #15 (permalink)  
Antiguo 04/05/2006, 06:23
Avatar de pyanqn  
Fecha de Ingreso: noviembre-2005
Mensajes: 331
Antigüedad: 18 años, 5 meses
Puntos: 8
De acuerdo hummm

el trabajo que esta haciendo Geri, es un trabajo tipico de los que se piden en materia como redes o teleprocesamiento en una carrera informatica, o por lo menos así me toco a mi, lo que suguiero, es que despues de estudiar durante casi 4 meses protocolos, servicios y capas. Sabemos que la comunicación entre la capa de aplicación y la capa de transporte se hace por medio de sockets, y la cuestion de no usar un servidor, es para no centralizar datos, aunque por supuesto puede ser que los requerimientos en tu desarrollo involucren un control centralizado, para poder hacer auditorias online, o poder definir perfiles de moderadores, etc...

La question a mi parecer, y concuerdo con GreenEyed, es que lo que buscamos son soluciones, y por supuesto haciendo detras un buen analisis de lo que necesitamos, asi pues si la solución mas economica es usar RMI, bien, pero nadie pude decir que es un error. A lo mejor no digiste que se trata de un desarrollo en tiempo record, o que es simplemente una decision de diseño.

Saludos.
  #16 (permalink)  
Antiguo 04/05/2006, 06:38
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Hola:

He cogido un ejemplo que tengo de rmi y me he puesto a jugar. Efectivamente, el tema de java.policy y el segurityManager no es necesario. Se puede eliminar sin problemas.

En cuanto al rmiregistry, no he conseguido que funcione sin él. Si no lo arranco, el servidor da una excepción en el Naming.rebind("nombre", objeto). ¿Cual es la forma de hacerlo sin arrancar rmiregistry?

De todas formas, te confieso que yo siempre he usado sockets (más que nada porque siempre me tengo que comunicar con programas que no son java), así que de rmi, salvo cuatro experimentos que he hecho, sé poco. Quizás por ello entiendo mejor los sockets y soy más partidario de ellos.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #17 (permalink)  
Antiguo 04/05/2006, 07:02
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Puedes crearte tu mismo un registry por codigo, despues de comprobar que no hay ninguno ya creado. Son 4 lineas.

Luego te las pongo pero tengo que ir a comer .
  #18 (permalink)  
Antiguo 04/05/2006, 08:01
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Mensaje

Código:
        Registry theRegistry = null;
        try
        {
          System.err.println( "Locating registry...");
          theRegistry = LocateRegistry.getRegistry(RMI_PORT);
          theRegistry.list();
          System.err.println( "Registry located!");
        }
        catch (Exception e)
        {
          // If ka-boom, then try to create our own registry
          try
          {
            System.err.println( "Registry not located.");
            System.err.println( "Creating registry...");
            theRegistry = LocateRegistry.createRegistry(RMI_PORT);
            theRegistry.list();
            System.err.println( "Registry created!");
          }
          catch (Exception e2)
          {
            System.err.println( "Error creating registry:"+ e2.getMessage());
            theRegistry = null;
          }
        }
        if (theRegistry != null)
        {
          System.err.println("Binding XXX to registry...");
          theRegistry.rebind("Nombre", XXX);
          System.err.println( "XXX bound!");
        }
        else
        {
         ...// Errores
        }
Con un solido control de errores y trazas salen algo más de cuatro, jejeje, pero vamos, se entiende . Las trazas y comentarios en "lengua de Shakespeare" por que es de un framework open source que programo, supongo que con claros.

Si no tienes que comunicarte con Java, está claro que RMI no sirve. Sin embargo, yo para según que optaría antes por CORBA o Web Services. Más que nada por que en cuanto te empiezas a meter en configuraciones flexibles, seguridad, proxies HTTP para evitar firewalls, diferencias de encoding entre clientes (ISO-8859-1, UTF-8...), diferencias de tamaño de tipos (no todos los int tienen el mismo numero de bytes en todos los lenguajes, p.e.), diferencias de codificacion de bytes (little endian, big endian...) etc, pues prefiero algo que ya lo tenga solucionado para centrarme en el "meollo" de mi programa y no en las comunicaciones.

Eso sí, a veces no hay más remedio. Pero habiendo probandolo todo, no me lanzo en seguida a por los sockets a bajo nivel. Es como saber la teoría de los ficheros detrás de una BDD. Está bien saberla pero si no es imprescindible, yo prefiero usar una BDD ya hecha que montarme una yo.

Nota: El SecurityManager en RMI es imprescindible únicamente cuando vas a realizar carga dinámica de classes en Runtime, una opción muy útil pero muchas veces no utilixada en RMI. En los ejemplos casi todo el mundo pone los SecurityManager, pero la mayoría no saben por qué, o lo hacen para no tener que dar explicaciones de cuando si y cuando no ponerlo .

Un saludo
  #19 (permalink)  
Antiguo 04/05/2006, 10:58
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Gracias. Anotado.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #20 (permalink)  
Antiguo 04/05/2006, 12:14
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Y así en off-topic, grácias por añadir tus tutoriales al Rincón Java . Ya han seguido el enlace 5 personas... desde ayer por la tarde que lo aprobe .
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:36.