Archivo

Archive for the ‘glassfish’ Category

PushServer + Jetty + Primefaces + WebSockets = PrimePush

abril 10, 2012 6 comentarios

Después de haber recorrido internet buscando a una solución para implementar AjaxPush con el framework para JSF de Primefaces 3, pues al fin lo he logrado, como nos comentan los creadores de primefaces dentro de la documentación oficial, para hacer este tipo de implementaciones es necesario crear un servidor paralelo a nuestra aplicación, este va ser un servidor de Push y se va a encargar exclusivamente de ese trabajo, conservando nuestro proyecto mucho más modular y escalable. Actualmente nos dicen que solo existe soporte para el servidor push implementado con las librerías de jetty, así que para comprobarlo he realizado unas cuantas pruebas obteneniendo un resultado excelente. Como se realizó esto lo voy a mostrar ahora:

  1. Lo primero que debemos hacer es descargar la librería de Jetty, en este casó la última versión que he podido encontrar es Jetty 8.1.2.
  2. Luego voy a crear un proyecto java estándar como los de escritorio o de consola en Netbeans 7.1.
  3. Agregar estas librerías al proyecto.
    jetty-websocket-8.1.2.v20120308.jar
    servlet-api-3.0.jar
    jetty-server-8.1.2.v20120308.jar
    jetty-servlet-8.1.2.v20120308.jar
    jetty-annotations-8.1.2.v20120308.jar
    jetty-io-8.1.2.v20120308.jar
    jetty-util-8.1.2.v20120308.jar
    jetty-http-8.1.2.v20120308.jar
    jetty-security-8.1.2.v20120308.jar
    jetty-continuation-8.1.2.v20120308.jar
  1. Creamos una clase principal con un método main como está.
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import servlet.PushServlet;

/**
* @author christmo
*/
public class JettyServerPush {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8081);

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        context.addServlet(new ServletHolder(new PushServlet()), "/*");

        server.start();
        server.join();
    }
}

Luego lo que queda es agregar la clase PushServlet que se tiene que desplegar con el servicio de websockets, esta clase la podemos encontrar íntegra en el código de primefaces, yo he hecho un par de modificaciones para hacer las pruebas pero uds la pueden personalizar como gusten.

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;

public class PushServlet extends WebSocketServlet {

    private static final long serialVersionUID = 1L;

    private final Map<String,Set> connectedClients = new ConcurrentHashMap>();

    @Override
    public void init() throws ServletException {
        super.init();
        String[] channels = {"chat","counter"};

        for(String channel : channels) {
            this.connectedClients.put(channel, new CopyOnWriteArraySet());
        }
    }

    @Override
    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
        String channel = request.getRequestURI().split("/prime-push/")[1];
        System.out.println("Canal:"+channel);
        return new PrimeWebSocket(channel);
    }

    private class PrimeWebSocket implements WebSocket, WebSocket.OnTextMessage {
        Connection connection;
        String channel;

        public PrimeWebSocket(String channel) {
            this.channel = channel;
        }

        public void onClose(int closeCode, String message) {
            connectedClients.get(this.channel).remove(this);
        }

        public void onOpen(Connection connection) {
            this.connection = connection;
            connectedClients.get(this.channel).add(this);
        }

        public void onMessage(String message) {
            System.out.println(message);
            try {
                for(PrimeWebSocket ws : connectedClients.get(this.channel)) {
                    ws.connection.sendMessage(message);
                }
            }catch(IOException e) {
                System.out.println(e);
            }
        }
    }
}

Finalmente ejecutamos nuestro servidor Jetty el cual ya es un servidor de PUSH, este está corriendo en el puerto 8081, podemos hacer pruebas rápidamente a través de esta página http://websocket.org/echo.html donde tenemos un cliente de websockets.

Lo que debemos poner para probar es está ruta ws://localhost:8081/prime-push/counter y conectar, si nos aparece el mensaje conectado pues todo ha salido muy bien y el servidor está listo, podemos hacer pruebas con este enviando algo desde allí y abriendo esa página en más pestañas.

Cliente Primefaces – PrimePush

Para hacer la misma prueba desde un proyecto con primefaces debemos crear un proyecto web, descargar la librería de primefaces añadirla al proyecto que estamos creando y haremos lo siguiente:

Crearemos un archivo JSF con el nombre de index.xhtml y pondremos lo que se muestra a continuación.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui" >
    <h:head>
        <title>Facelet Title</title>
        <style type="text/css">
            .display {
                font-size: 36px !important;
            }
        </style>

        <script type="text/javascript">
            //<![CDATA[
            function handleMessage(evt, data) {
                $('.display').html(data);
            }
            //]]>
        </script>
    </h:head>
    <h:body>
        <h:form>
            <h:outputText value="#{beanPush.count}" styleClass="ui-widget display" />

            <br />

            <p:commandButton value="Click" actionListener="#{beanPush.increment}" />
        </h:form>

        <p:push onmessage="handleMessage" channel="counter" />

    </h:body>
</html>

Luego crearemos una clase dentro de código que maneje la lógica de la aplicación en este caso un contador, este va ser nuestro manejador de bean.

package bean;

import java.io.Serializable;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.context.RequestContext;

/**
 * @author christmo
 */
@ManagedBean
@ApplicationScoped
public class BeanPush implements Serializable {

    private int count;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void increment() {
        count++;
        RequestContext.getCurrentInstance().push("counter", count);
    }
}

Finalmente necesitamos hacer que la aplicación apunte a nuestro servidor de Push creado anteriormente eso lo debemos hacer añadiendo lo siguiente dentro del archivo web.xml

    <context-param>
        <param-name>primefaces.PUSH_SERVER_URL</param-name>
        <param-value>ws://localhost:8081/</param-value>
    </context-param>

Y eso es todo espero que les funcione, si todo lo que escribí por aquí sonó a chino aquí les dejo los proyectos para que los revisen…

Proyectos 😉

Saludos

Christian Mora

@christmo

Anuncios
Categorías:glassfish, Java, JSF, Linux, NetBeans, Web 2.0 Etiquetas:

Levantar Glassfish por consola en UBUNTU

abril 7, 2009 5 comentarios

Vamos ha ver como se hace para levantar un proyecto web, en el servidor de aplicaciones Glassfish desde la consola, regularmente como desarrolladores nos hemos encontrado con paquetes *.war, los cuales son el empaquetado de toda la aplicación web lista para funcionar, cuando instalamos netbeans también se instala glassfish pero a veces es demasiado pesado arrancar primero el IDE y después levantar el servidor de aplicaciones, para se cuenta con uno practico comando para solo levantar el servidor.

Debemos ir primero a la carpeta donde tenemos instalado glassfish y a bin, algunos lo podemos tener instalado por defecto en esta ruta:

$ cd glassfish-v2ur2/bin/

o

$ cd /usr/local/glassfish/bin/

Allí ponemos:

$ ./asadmin start-domain domain1

y esperamos un momento y ya está:

Ahora solo nos toca abrir un navegador y poner:

http://localhost:4848/

para entrar a la interfaz de administración de glassfish recuerda que cuando se instaló netbeans nos pidió un user y un password allí van, por defecto son “user: admin” y “password: adminadmin”, desde allí ya podremos gestionar todos los proyectos *.war que tengamos.

Para detener Glassfish pondremos los mismo solo que con la palabra stop:

$ ./asadmin stop-domain domain1

Eso es todo, por cierto este mismo comando lo podemos usar en Window$ solo debemos ponerlo en la consola dentro de la carpeta bin de glassfish de archivos de programa, espero que les sirva tanto como a mi.

Saludos…

christmo

Categorías:glassfish, Java, JSF, Linux, NetBeans Etiquetas: