feat(DevWeb): Create WebsocketToolkit.js

This commit is contained in:
Lucàs
2024-04-23 20:06:17 +02:00
parent 5bc33f7754
commit 2f9d2546fb
8 changed files with 137 additions and 118 deletions
+1 -1
View File
@@ -91,7 +91,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>16</source><target>16</target></configuration></plugin>
</plugins>
</build>
</project>
@@ -1,6 +1,10 @@
package uppa.project.json.websocket;
import com.google.gson.Gson;
public class Message {
private final static Gson gson = new Gson();
private final String type;
private final String data;
@@ -17,6 +21,10 @@ public class Message {
return data;
}
public String toJson() {
return gson.toJson(this);
}
@Override
public String toString() {
return "Message{" + "type=" + type + ", data=" + data + '}';
@@ -5,45 +5,50 @@ import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.RemoteEndpoint;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import uppa.project.database.dao.DAO;
import uppa.project.database.dao.DAOException;
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
import uppa.project.database.pojo.User;
import uppa.project.json.websocket.Message;
@ServerEndpoint(value = "/ws/connected-users")
@ServerEndpoint(value = "/ws/users/{user_id}")
public class ConnectedUsersWS {
public static final HashMap<Session, User> connections = new HashMap<>();
public static final HashMap<Session, User> users = new HashMap<>();
private static final Gson gson = new Gson();
@OnOpen
public void onOpen(Session session) {}
public void onOpen(Session session, @PathParam("user_id") String userId) throws DAOException {
Message message;
final DAO<User> userDAO = new Game_JPA_DAO_Factory().getDAOUser();
private void broadcastConnectedUsers() {
Gson gson = new Gson();
User[] connectedUsers = connections.values().toArray(new User[0]);
int id = Integer.parseInt(userId);
User user = userDAO.findById(id);
Message websocketObject = new Message("userList", gson.toJson(connectedUsers));
String message = gson.toJson(websocketObject);
// Send the new user to all connected users
message = new Message("addUser", gson.toJson(new SimpleUser(user)));
broadcast(message.toJson());
for (Session session : connections.keySet()) {
RemoteEndpoint.Basic remote = session.getBasicRemote();
try {
remote.sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
// Send all connected users to the new user
users.put(session, user);
ArrayList<SimpleUser> connectedUsers = new ArrayList<>();
for (User u : users.values()) connectedUsers.add(new SimpleUser(u));
message = new Message("init", gson.toJson(connectedUsers));
session.getAsyncRemote().sendText(message.toJson());
}
@OnClose
public void onClose(Session session) {
connections.remove(session);
users.remove(session);
// Update connected users list
broadcastConnectedUsers();
Message message = new Message("removeUser", gson.toJson(new SimpleUser(users.get(session))));
broadcast(message.toJson());
}
@OnError
@@ -53,13 +58,26 @@ public class ConnectedUsersWS {
@OnMessage
public void onMessage(String message, Session session) {
Gson gson = new Gson();
Message websocketMessage = gson.fromJson(message, Message.class);
// Do nothing
}
if (websocketMessage.getType().equals("linkUserSession")) {
User user = gson.fromJson(websocketMessage.getData(), User.class);
connections.put(session, user);
broadcastConnectedUsers();
private static void broadcast(String message) {
for (Session session : users.keySet()) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static class SimpleUser {
public int id;
public String username;
public SimpleUser(User user) {
this.id = user.getId().intValue();
this.username = user.getUsername();
}
}
}
@@ -1,95 +1,63 @@
<jsp:useBean id="user" scope="session" type="uppa.project.database.pojo.User"/>
<%@tag description="component/connected-user-list" pageEncoding="UTF-8" %>
<%@tag import="com.google.gson.Gson" %>
<%@tag import="uppa.project.database.pojo.User" %>
<%@taglib prefix="component" tagdir="/WEB-INF/tags/components" %>
<%@attribute name="anonymous"%>
<table id="connected-user-list" class="table is-fullwidth">
<thead>
<tr>
<th>Utilisateur</th>
<%-- <th>Nombre de parties</th>--%>
<%-- <th>Victoires (%)</th>--%>
<%-- <th>Clics corrects (%)</th>--%>
<%-- <th>Clics rapides (%)</th>--%>
<%-- <th>Action</th>--%>
</tr>
</thead>
<tbody></tbody>
</table>
<script defer type="module">
const tbodyElement = document.querySelector('#connected-user-list tbody');
import WebsocketToolkit from "${pageContext.request.contextPath}/static/js/WebsocketToolkit.js";
// effacer ce qu'il y a apres /project_war_exploded
const url = new URL(window.location.href);
url.pathname = "${pageContext.request.contextPath}/ws/connected-users";
url.protocol = "ws:"
let users = [];
function updateUsers() {
const table = document.querySelector('#connected-user-list tbody');
const websocket = new WebSocket(url);
// Clear the table
table.innerHTML = '';
<%
Gson gson = new Gson();
User user = (User) request.getSession().getAttribute("user");
%>
websocket.onopen = () => {
const linkUserSession = {
type: 'linkUserSession',
data: JSON.stringify(<%= gson.toJson(user) %>)
}
websocket.send(JSON.stringify(linkUserSession));
}
websocket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'userList') {
const users = JSON.parse(data.data);
updateUserList(users);
}
}
websocket.onclose = () => {}
websocket.onerror = (error) => console.error(error);
function updateUserList(users) {
tbodyElement.innerHTML = '';
// Add the users to the table
users.forEach(user => {
const trElement = document.createElement('tr');
const tdElement = [
document.createElement('td'),
// document.createElement('td'),
// document.createElement('td'),
// document.createElement('td'),
// document.createElement('td'),
// document.createElement('td')
];
// const buttonElement = document.createElement('button');
const tr = document.createElement('tr');
const td = document.createElement('td');
tdElement[0].textContent = user.username;
// tdElement[1].textContent = user.nbPlayedGames;
// tdElement[2].textContent = user.WinRate + '%';
// tdElement[3].textContent = user.rightClickPercentRate + '%';
// tdElement[4].textContent = user.rapidClickPercentRate + '%';
td.dataset.id = user.id;
td.textContent = user.username;
// If it's not the current user, we can display the button
<%--if (user.id !== <%= user.getId() %>) {--%>
<%-- buttonElement.classList.add('button', 'is-light');--%>
<%-- buttonElement.textContent = 'Inviter';--%>
<%-- // TODO Ajouter l'événement click--%>
<%--}--%>
// tdElement[5].appendChild(buttonElement);
trElement.appendChild(tdElement[0]);
// trElement.appendChild(tdElement[1]);
// trElement.appendChild(tdElement[2]);
// trElement.appendChild(tdElement[3]);
// trElement.appendChild(tdElement[4]);
// trElement.appendChild(tdElement[5]);
tbodyElement.appendChild(trElement);
tr.appendChild(td);
table.appendChild(tr);
});
}
// Create a new WebSocket
const url = new URL(window.location.href);
url.pathname = "${pageContext.request.contextPath}/ws/users/${user.id}";
url.protocol = "ws:"
const ws = new WebsocketToolkit(url);
ws.onOpen(() => console.log("Connected to the server"));
ws.onMessage("init", (data) => {
users = data;
updateUsers();
});
ws.onMessage("addUser", (data) => {
users.push(data);
updateUsers();
});
ws.onMessage("removeUser", (data) => {
users = users.filter(user => user.id !== data.id);
updateUsers();
});
ws.onError((error) => console.error(error));
ws.onClose(() => console.log("Disconnected from the server"));
</script>
@@ -6,13 +6,13 @@
<% if (session.getAttribute("user") != null) { %>
<a class="navbar-item" href="${pageContext.request.contextPath}/lobby">
<img src="${pageContext.request.contextPath}/static/img/CardsRushLogoBlack.svg" height="260">
<img src="${pageContext.request.contextPath}/static/img/CardsRushLogoBlack.svg" height="260" alt="Logo">
</a>
<% } else { %>
<a class="navbar-item" href="${pageContext.request.contextPath}/">
<img src="${pageContext.request.contextPath}/static/img/CardsRushLogoBlack.svg" height="260">
<img src="${pageContext.request.contextPath}/static/img/CardsRushLogoBlack.svg" height="260" alt="Logo">
</a>
<% } %>
@@ -0,0 +1,13 @@
export default class Message {
constructor(rawMessage) {
// Parse the message
const message = JSON.parse(rawMessage);
message.data = JSON.parse(message.data);
console.log(message);
// Set the message properties
this.type = message.type;
this.data = message.data;
}
}
@@ -0,0 +1,31 @@
import Message from "./Message.js";
export default class WebsocketToolkit {
action = {}
constructor(url) {
this.url = url;
this.ws = new WebSocket(url);
}
onOpen(callback) {
this.ws.onopen = callback;
}
onMessage(type, callback) {
this.action[type] = callback;
this.ws.onmessage = (event) => {
const message = new Message(event.data);
this.action[message.type](message.data)
};
}
onClose(callback) {
this.ws.onclose = callback;
}
onError(callback) {
this.ws.onerror = callback;
}
}
@@ -1,19 +0,0 @@
const nbColorsElement = document.getElementById("nbColors");
const nbValuesElement = document.getElementById("nbValues");
const nbRoundsElement = document.getElementById("nbRounds")
/**
* Mise à jour du nombre de rounds max en fonction du nombre de couleurs et de valeurs séléctionnés
*/
function updateOnChange() {
nbRoundsElement.max = nbColorsElement.value * nbValuesElement.value;
nbRoundsElement.value =
(nbRoundsElement.value > nbRoundsElement.max)
? nbRoundsElement.max
: nbRoundsElement.value
;
}
nbColorsElement.addEventListener("change", updateOnChange);
nbValuesElement.addEventListener("change", updateOnChange);