DEV Community

aristides villarreal
aristides villarreal

Posted on • Updated on

Jakarta WebSocket enviando mensajes

Enviar mensajes a todos los usuarios

Para utilizar WebSocket en nuestras aplicaciones Jakarta EE, seguimos los siguientes pasos:

  • Configurar el archivo web.xml

<context-param>
 <param-name>jakarta.faces.ENABLE_CDI_RESOLVER_CHAIN</param-name>
     <param-value>true</param-value>
</context-param>
<context-param>
 <param-name>jakarta.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
   <param-value>true</param-value>
</context-param> 
Enter fullscreen mode Exit fullscreen mode

En el archivo template.xhtml
Image description

agregar dos commandButton

<p:commandButton id="sendMessageAll" 
 action="#{webSocketDomain.sendMessageAll('all','user')}" 
 value="sendMessageUserAll">
  <f:ajax />
</p:commandButton>

<p:commandButton id="sendMessageProyecto" 
action="#{webSocketDomain.sendMessageProyecto('proyecto ',loginFaces.userLogged)}" value="sendMessageProyecto">
 <f:ajax />
</p:commandButton>

Enter fullscreen mode Exit fullscreen mode

El primero se usará para enviar un mensaje a todos los usuarios y el segundo para enviar un mensaje a un usuario en específico.

Image description

Al presionar el primer botón todos los usuarios recibirán un mensaje como el siguiente

Image description

Cree la interface

public interface WebSocketPlantilla {

    public void sendMessageAll(String message, String scoped);

    public void sendMessageProyecto(String message, User user);

    public void sendMessageProyectoMultiple(String message, List<User> userList);

    public void sendMessageSprint(String message, User user);


    public void sendMessageSprintMultiple(String message, List<User> userList) ;

    public void sendMessageTablero(String message, User user);

    public void sendMessageTableroMultiple(String message, List<User> userList);

    public Collection<Long> collectionOfUserList(List<User> userList);
}


Enter fullscreen mode Exit fullscreen mode

Ahora es necesario crear una clase que denominaremos a modo de ejemplo como WebSocketController.
En esta clase utilizaremos PushContext para enviar los mensajes mediante WebSocket.

@ViewScoped
@Named
public class WebSocketController implements Serializable, WebSocketPlantilla {

    @Inject
    @Push
    private PushContext proyectoChannel;

    @Inject
    @Push
    private PushContext sprintChannel;

    @Inject
    @Push
    private PushContext tableroChannel;

    @Inject
    @Push
    PushContext allChannel;

    /**
     *
     * @param message
     * @param user
     */
    @Override
    public void sendMessageProyecto(String message, User user) {
        proyectoChannel.send(message, user.getIduser());

    }

    /**
     * *
     * Envia mensaje a muchos usuarios
     *
     * @param message
     * @param userList
     */
    @Override
    public void sendMessageProyectoMultiple(String message, List<User> userList) {
        proyectoChannel.send(message, collectionOfUserList(userList));
    }

    /**
     *
     * @param message
     * @param user
     */
    @Override
    public void sendMessageSprint(String message, User user) {
        sprintChannel.send(message, user.getIduser());

    }

    /**
     * *
     * Envia mensaje a muchos usuarios
     *
     * @param message
     * @param userList
     */
    @Override
    public void sendMessageSprintMultiple(String message, List<User> userList) {

        sprintChannel.send(message, collectionOfUserList(userList));
    }

    /**
     *
     * @param message
     * @param user
     */
    @Override
    public void sendMessageTablero(String message, User user) {

        tableroChannel.send(message, user.getIduser());

    }

    /**
     * *
     * Envia mensaje a muchos usuarios
     *
     * @param message
     * @param userList
     */
    @Override
    public void sendMessageTableroMultiple(String message, List<User> userList) {

        tableroChannel.send(message, collectionOfUserList(userList));
    }

    @Override
    public void sendMessageAll(String message, String scoped) {
       allChannel.send(message, "user");
    }

    @Override
    public Collection<Long> collectionOfUserList(List<User> userList) {
        Collection<Long> result = new ArrayList<>();
        try {
            userList.forEach(u -> {
                result.add(u.getIduser());
            });
        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return result;
    }

}

Enter fullscreen mode Exit fullscreen mode

En el archivo template.xhtml añada

 <script>
            function handleMessageAllChannel(message, channelName, event) {
                alert('[handleMessageAllUser]: ' + message );

                remoteCommandWebSocketAll();

            }
            function handleMessageProyectoChannel(message, channelName, event) {
                alert('[handleMessageProyecto]: ' + message);


            }

</script>

Enter fullscreen mode Exit fullscreen mode

Añada un f:websocket para escuchar en el canal allChannel y un p:remoteCommnad para invocar métodos al recibir la notificación.

Observe que se utiliza user="user".

  <f:websocket channel="allChannel"  user="user" onmessage="handleMessageAllChannel" />

 <p:remoteCommand name="remoteCommandWebSocketAll" action="#{loginFaces.webSocketListenerMethod}" 
                                 update="template_growl_timesession" />
Enter fullscreen mode Exit fullscreen mode

En la clase LoginFaces añada

 // <editor-fold defaultstate="collapsed" desc="String websocketListenerMethod()">
    public String webSocketListenerMethod() {
        try {

            FacesUtil.successMessage("desde el websocket");

        } catch (Exception e) {
            FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
        }
        return "";
    }

Enter fullscreen mode Exit fullscreen mode

Que enviara un mensaje mediante un p:growl de Primefaces

Image description

Enviar un mensaje a un usuario específico

Edite otra pagina que se habilite luego de autentificarse en el sistema, en este ejemplo: dashboard.xhtml

Image description

Añada un websocket, observe que se usa el canal proyectoChannel y el usuario que ingreso al sistema que se almacena en loginFaces.userLogged.iduser.

<f:websocket channel="proyectoChannel" user="#{loginFaces.userLogged.iduser}" onmessage="handleMessageProyectoChannel"/>                
Enter fullscreen mode Exit fullscreen mode

De esta manera se envía una notificación solo al usuario especificado en el parámetro user.

Image description

Top comments (0)