RESPUESTA A LA PREGUNTA 6067 - JAVA Vamos a aprovechar lo que aprendimos en los últimos capítulos para hacer un programita de chat en Java; un servidor correrá un programa al que se podrán conectar varios clientes y charlar entre ellos. Por qué usamos un servidor? No se olviden que un applet sólo puede dialogar con la máquina a la que se conectó. De este modo, usamos un server para que intercambie los datos entre los clientes. Hagamos un esquema de los programas a desarrollar: LADO SERVIDOR: objeto: ChatProject solamente para crear un objeto de tipo ChatServer y pasarle el número de puerto a usar. objeto: ChatServer se encarga de esperar a los clientes, abre un thread (CSThread) cada vez que llega uno y lo cierra cada vez que uno se desconecta. También envía a todos los clientes los mensajes que envía uno de ellos. objeto: CSThread uno por cliente, se encarga de abrir los streams de entrada y salida, recibir mensajes (que pasa al ChatServer para que distribuya) y enviar los mensajes que le pasa el ChatServer. LADO CLIENTE: página: Chat.htm desde esta página se abre el applet para conectarse al servidor objeto: CCInterface crea la ventana de interface, pide el alias del cliente, crea un objeto ChatClient que es el que va a dialogar con el servidor, le manda los mensajes que entra el usuario al ChatClient y muestra los mensajes que recibe de él. objeto: ChatClient establece la conexión, crea los streams de entrada y salida, manda al CCInterface los mensajes que recibe del servidor (para que los muestre) y envía al servidor los mensajes que recibe del CCInterface. Hagamos un pequeño esquema de cada uno. El Servidor El programa que se arranca en el servidor (y que estará corriendo constantemente) es muy sencillo: // Archivo: ChatProject.java // Compilar: javac ChatProject.java // Ejecutar: java ChatProject public class ChatProject { public static void main(String argv[]) { ChatServer servidor = new ChatServer(5000); } } Nuestro objeto ChatServer es un poquito más complejo: // Archivo: ChatServer.java // Compilar: javac ChatServer.java // Se crea y ejecuta desde ChatProject public class ChatServer { // se ejecuta siempre... hasta Control-Break al menos! public ChatServer(int puerto) { ESTABLECER_CONEXION_CON_SERVER; do { ESPERAR_CONEXION_CLIENTE; ARRANCAR_THREAD_PARA_CLIENTE; AGREGAR_CLIENTE_A_LISTA; } while (true); // siempre! } // para enviar mensajes a todos los clientes: public synchronized void sendAll(...) { for (int i=0; i JavaChat 1.0 JavaChat 1.0 Copyright © 1997 by Jorge Bourdette
Es parte del curso Java desde Cero
Recomendamos grabar en un mismo directorio la página HTML y las clases ChatClient.class y CCInterface.class. En el mismo o en otro estarán ChatProject.class, ChatServer.class y CSThread.class. Para que los clientes se puedan conectar, hay que correr "java ChatProject" y dejarlo andando indefinidamente en el servidor (puede ponerse en la lista de programas de arranque automático del servidor). El programa de interfase será más o menos así: // Archivo: CCInterface.java // Compilar: javac CCInterface.java // Se carga y ejecuta al entrar a la página Chat.htm public class CCInterface extends Applet { boolean conectado; public void init() { ARMAR_VENTANA_ENTRADA_ALIAS; ESPERAR_QUE_ENTRE_ALIAS; BORRAR_VENTANA; ARMAR_VENTANA_CHAT; CREAR_THREAD_CLIENTE_ChatClient; LEER_NOMBRE_SERVER; CONECTARSE_A_SERVER; // Activar thread cliente ( SI NO LO LOGRA, PARAR TODO...); } public void destroy() { if (conectado) DESCONECTAR_CLIENTE; MATAR_CLIENTE_ChatClient; } public boolean handleEvent(Event e) { if (PRESIONA_ENTER) DISPARAR_EVENTO_BOTON_ENVIAR; if (PRESIONA_BOTON_ENVIAR && ESTA_EN_PANTALLA_ALIAS) { miNombre = TEXTO_ENTRADO; return true; } if (PRESIONA_BOTON_ENVIAR && ESTA_EN_PANTALLA_CHAT) { if (conectado) ENVIAR_TEXTO_VIA_ChatClient; else writeMsg("NO ESTA CONECTADO!"); BORRAR_CAMPO_DE_ENTRADA; return true; } // para evitar que escriba en cuadro de presentación de mensajes: if (TOCA_EN_CUADRO_MENSAJES) return true; // para procesar otros eventos: return false; } // Para mostrar mensajes en cuadro de presentación de mensajes: public void writeMsg(String...) { AGREGAR_MENSAJE_A_CUADRO_MENSAJES; } } El cliente, el thread que se encarga de la comunicación propiamente dicha, es: // Archivo: ChatClient.java // Compilar: javac ChatClient.java // Se carga y ejecuta desde CCInterface.class public class ChatClient extends Thread { boolean running; public ChatClient(referencia al CCInterface, etc...) { INICIALIZAR; running = false; } public boolean connect(...) { CONECTARSE; ABRIR_STREAM_DE_ENTRADA; ABRIR_STREAM_DE_SALIDA; ( SI NO LO LOGRA running = false ); if (running) sendToken("llega"); // le avisa al server running = true; } public boolean disconnect() { sendToken("se va"); // le avisa al server running = false; CERRAR_SOCKET; } // mensajes a enviar al server cuando se conecta o desconecta private boolean sendToken(String s) { ENVIAR_MSG_A_SERVER( "[" + alias + " " + s + "]" ); } // envía un mensaje al server poniendo antes quién lo envía public boolean sendInfo(String s) { ENVIAR_MSG_A_SERVER( alias + "> " + s ); } // ejecutar continuamente hasta que lo maten... public void run() { while (running) { ESPERAR_MENSAJE_DEL_SERVER; MOSTRAR_MSG_VIA_CCInterface; } } No confundan aquí los distintos threads relacionados con los clientes! El servidor maneja sus propios threads, los del cliente corren localmente en el mismo. Hagamos un esquema para cuando hay tres clientes conectados: En la próxima lección desarrollaremos los programas (todos!). Jorge Bourdette jpb@amarillas.com