domingo, agosto 25, 2013

Comucación Socket TCP con Java EE



Esta vez traigo un escenario con el cual tuve algunas dificultades para realizar el proyecto.

Lo llame:

Mostrar información en pagina web a partir de un Socket en Java de forma dinámica.



Tecnologias utilizadas:
Java 1.6
DWR 2.0.10
jqGrid 4.5.2


Escenario:

En la imagen que muestro al inicio trato de proyectar la forma que funciona este proyecto, por una parte existe un canal de comunicación  socket tcp que envía información JSON, esta información se realiza de manera constante por lo que en  un proyecto web con el Framework DWR se  lee la información para procesarla y mostrarla en una pagina con un control jqGrid.

La forma en que se realizo el proyecto fue maso menos así:

Vamos a crear un proyecto que de la salida por un socket  la cadena JSON y así el proyecto web pueda leerlo y mostrarlo en jqGrid de forma dinámica:

ServidorTCP

Paso 1:
Generamos nuestro proyecto en file->New->Java Project

Aisgnamos un nombre, en este caso ServidorTCP


Click en Finish para terminar crear nuestro proyecto

Paso 2:

Al generar el proyecto debe visualizar maso menos asi:

Creamos un paquete en src, com.ejemplo.servidor

Dentro de com.ejemplo.servidor, creamos una clase llamada Servidor.java,

Ha esta clase le colocamos el siguiente código.

package com.ejemplo.servidor;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Servidor extends Thread {

public Servidor() throws IOException {

}

public void run() {

ServerSocket welcomeSocket;
int i = 0;

long start;

DateFormat df = new SimpleDateFormat(
"HH 'hours', mm 'mins,' ss 'seconds'");

try {
welcomeSocket = new ServerSocket(9546);

while (true) {

System.out.println("Preparando... ");
Socket connectionSocket = welcomeSocket.accept();
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());

while (true) {

i++;
try {

start = System.currentTimeMillis();

outToClient.writeBytes("{\"id\":\"" + i
+ "\" ,\"mensaje\":\"mensaje " + i
+ "\",\"hora\":\"" + df.format(new Date(start))
+ "\"}\n");
// System.out.println("{\"id\":\""+ i +
// "\" ,\"mensaje\":\"mensaje "+i
// +"\",\"hora\":\""+df.format(new
// Date(start))+"\"}\n");
Thread.sleep(1000);
} catch (Exception e) {

break;
}
}

}
} catch (IOException e) {
e.printStackTrace();
}

}

public static void main(String[] args) {

try {
Thread t = new Servidor();
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

al pegar el código, lo que resta es dar click derecho sobre la clase y elegir Run as -> Java Application, en nuesta consola se mostrara como se ve en la imagen

Una vez finalizado, el proyecto esta enviando cadenas JSON por un socket específicamente por el puesto 9546, para que el prpyecto web pueda leer.

{"id":" 1" ,"mensaje":"mensaje 1","hora":" ");

Creando el proyecto Web 

Paso 1:
Creamos proyecto Web desde File -> New -> Dynamic Web Project tal como se ve en las siguientes imágenes:





Paso 2:

Al crear el proyecto debe quedar una estructura similar a la que se muestra

dentro de src creamos los paquetes com.example.dwr y com.example.grid, para el primero colocamos la clase Inicia.java y en el segundo colocamos la clase HiloLectura.java con el siguiente código para cada clase.

package com.example.dwr;

import java.io.InputStream;
import java.net.Socket;
import java.util.Properties;
import java.util.Scanner;

import javax.servlet.ServletContext;

import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.util.Logger;

import com.example.grid.HiloLectura;


public class Inicia 
{
private ServerContext sctx;
    private transient boolean active = true;
    private static final Logger log = Logger.getLogger(Inicia.class);
private Socket so = null;
private Scanner sc = null;

public Inicia()
    {
        ServletContext servletContext = WebContextFactory.get().getServletContext();
        sctx = ServerContextFactory.get(servletContext);
    }

    public synchronized void toggle()
    {
        //active = !active;
        System.out.println("!!!!!!!!"+active);
        if (active)
        {
          String server = "";
    int port = 0;

            try{
       
        Properties properties = new Properties();
        Properties configuration = new Properties();
                InputStream in = getClass().getResourceAsStream("/socket.properties");
                configuration.load(in);
                server=configuration.getProperty("ipOrigen");
                port=Integer.valueOf(configuration.getProperty("puertoOrigen"));

                this.so = new Socket(server, port);
                this.sc = new Scanner(so.getInputStream());
                HiloLectura hiloInter = new HiloLectura(so,sc,sctx);
                Thread theReader = new Thread(hiloInter);
                theReader.start();
                System.out.println("!!!!!!!!Generaste Hilo");
                active=false;
        }catch(Exception e){
        e.printStackTrace();
       
       
        }
        }
    }

}




package com.example.grid;

import java.net.Socket;
import java.util.Collection;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.log4j.Logger;
import org.directwebremoting.ServerContext;
import org.directwebremoting.proxy.dwr.Util;


public class HiloLectura implements Runnable{
    
private Socket so = null;
private Scanner sc = null;

private ServerContext sctx;
 
    private static Logger logger = Logger.getLogger(HiloLectura.class);
    
    public HiloLectura(Socket so, Scanner sc,ServerContext sctx) {
    this.so = so;
this.sc = sc;
this.sctx=sctx;
}
    
    
    public HiloLectura (){
        
    }
    
    public  void run(){
        try{
           
        System.out.println("Inicia Hilo...");
    int i=0;
    System.out.println("..."+sc.hasNext());
    while (sc.hasNext()) {
    //System.out.println("....."+sc.nextLine());
    i++;
   
    Collection sessions = sctx.getScriptSessionsByPage("/EjemploGridDinamico/index.html");
                Util pages = new Util(sessions);
                pages.addFunctionCall("putDatos", sc.nextLine());
          
    }
       
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
  
    
}


Se debe mostrar la estructura como se ve en la imagen


Paso 3:
Ademas de crear los paquetes y las clases debemos importar las librerías WDR, log4j, commons etc como se ve en la imagen



Paso 4:
Agregar un  properties para leer el socket que trae la información a mostrar
en mi caso lo que contiene mi .properties es

#Desarrollo
ipOrigen = 192.168.0.9
puertoOrigen = 9546


Paso 5:
Una vez terminado la parte de negocio de java pasamos a crear la configuración del front del proyecto para poder visualizar la lectura del socket, agregamos enWebContent carpetas images, css y js como se muesta en la imagen:


Paso 6:
Seguido le colocaremos el código fuente de cada componente que necesitamos, para este caso necesitamos los sources de jqGrid 


Paso 7:
En la carpeta WEB-INF colocaremos el archivo dwr.xml con la siguiente información:


 
   
     
   
match="com.opensymphony.xwork2.ValidationAwareSupport" />


y el web.xml le colocaremos la siguiente información

   
   dwr
   uk.ltd.getahead.dwr.DWRServlet
 
 
   dwr
   /dwr/*
 
 
   index.html
 
 
   dwr-invoker
   uk.ltd.getahead.dwr.DWRServlet
   
     debug
     true
   
   
     activeReverseAjaxEnabled
     true
   
   
     pollAndCometEnabled
     true
   
   
     allowScriptTagRemoting
     true
   
   1
 
 
   dwr-invoker
   /dwr/*
 
 

Paso 8:
Agregamos a la carpeta js el archivo colocaDatos.js con el siguiente código:

function putDatos(jsonSocket){

if(jsonSocket!=null &&  jsonSocket!=""){

var str=jsonSocket;
 

if(typeof jsonSocket =='object')
{
 obj=jsonSocket;
}else{
//GRID
obj = JSON && JSON.parse(jsonSocket);

//obj=jQuery.parseJSON(jsonSocket);
}

  }
var data = {id:obj.id,mensaje:obj.mensaje,hora:obj.hora};
jQuery("#msj").jqGrid('addRowData','myrowid', data, 'first');
console.log(obj.mensaje);
}




Paso 9:
Una vez terminado entonces es hora de ejecutar click sobre el proyecto y Run as -> Run on Server




Y así es como debe verse el resultado, el grid debe estar llenando de forma que la comunicación con el socket sea por detrás y así se vea el efecto dinámico


Para cualquier aclaracion pues ahi dejo los source para que se note que si funciona




Saludos hasta la proxima



1 comentario:

  1. Anónimo10:05 a.m.

    Un tip, cuando estoy manejando gran cantidad de informacion, coloque este tag en la configuracion del web.xml

    maxWaitAfterWrite
    -1

    esto me ayudo a dibujar mas rapido en el grid.

    ResponderEliminar