Jakarta WebSocket enviando mensajes
Published: 2023-12-07 21:34:06

## Enviar mensajes a todos los usuarios

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

- Configurar el archivo web.xml
```java

<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> 
```

En el archivo template.xhtml 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r28rht36yyle1pgyiw59.png)

agregar dos commandButton

```html
<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>

```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1i6y4ohdh24q87nrj8ap.png)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qa75r82469ddrcpp1q71.png)

Cree la interface
```java
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);
}


```

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.

```java
@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;
    }

}

```
En el archivo template.xhtml añada

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

                remoteCommandWebSocketAll();

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


            }

</script>

```

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".

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

 <p:remoteCommand name="remoteCommandWebSocketAll" action="#{loginFaces.webSocketListenerMethod}" 
                                 update="template_growl_timesession" />
```

En la clase LoginFaces añada

```java
 // <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 "";
    }

```

Que enviara un mensaje mediante un p:growl de Primefaces

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gdlzfks7uoomvq7rxepg.png)




## 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk768yqc4voztr86wyws.png)

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.

```xhtml
<f:websocket channel="proyectoChannel" user="#{loginFaces.userLogged.iduser}" onmessage="handleMessageProyectoChannel"/>                
```

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ple90hh8qdka6qgfycx7.png)