I've searched the internet but all the documentation for the Jakarta repo is unsuccessful so far. There is literally nothing on how to deploy the endpoint. Obviously the endpoint is just a useless file unless its deployed. Below is the Websocket server endpoint.
package com.wsserver;
import java.io.IOException;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
@ServerEndpoint("/ws")
public class WebSocketEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("WebSocket opened: " + session.getId());
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message received: " + message);
try {
session.getBasicRemote().sendText("Echo: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println("WebSocket closed: " + session.getId());
}
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("WebSocket error: " + session.getId());
throwable.printStackTrace();
}
}
Here is the main.java file
package com.wsserver;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig;
import java.URI;
import java.http.WebSocket;
@ServerEndpoint("/ws")
public class Main {
public static void main(String[] args) throws Exception {
ServerEndpointConfig serverEndpoint = ServerEndpointConfig.Builder.create(WebsocketEndpoint.class, "/pathToRoot/").build();
}
}
websocket server pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0"
xmlns:xsi=";
xsi:schemaLocation=".0.0 .0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wsserver</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<mavenpiler.source>17</mavenpiler.source>
<mavenpiler.target>17</mavenpiler.target>
</properties>
<dependencies>
<!-- .fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.18.2</version>
</dependency>
<!-- .fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.18.2</version>
</dependency>
<!-- .fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<!-- .websocket/jakarta.websocket-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- .google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!-- .websocket/jakarta.websocket-client-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- .glassfish.tyrus.bundles/tyrus-standalone-client -->
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>2.2.0</version>
</dependency>
<!-- .json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20241224</version>
</dependency>
<!-- .mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
</dependency>
</dependencies>
</project>
Main.java seems to sucessfully build the websocket but how would I listen to events? Any insight would be great. Thank you.
here is the working websocket client that I am using to pass data to the websocket server:
package com.wsclient;
import java.io.IOException;
import java.URI;
import java.nio.ByteBuffer;
import jakarta.websocket.ClientEndpoint;
import jakarta.websocket.CloseReason;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
@ClientEndpoint
public class WebsocketClientEndpoint {
Session userSession = null;
private MessageHandler messageHandler;
public WebsocketClientEndpoint(URI endpointURI) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@OnOpen
public void onOpen(Session userSession) {
System.out.println("opening websocket");
this.userSession = userSession;
}
@OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing websocket");
this.userSession = null;
}
@OnMessage
public void onMessage(String message) throws IOException {
if (this.messageHandler != null) {
this.messageHandler.handleMessage(message);
}
}
@OnMessage
public void onMessage(ByteBuffer bytes) {
System.out.println("Handle byte buffer");
}
public void addMessageHandler(MessageHandler msgHandler) {
this.messageHandler = msgHandler;
}
public void sendMessage(String message) {
this.userSession.getAsyncRemote().sendText(message);
}
public static interface MessageHandler {
public void handleMessage(String message) throws IOException;
}
}
here is Main.java where I call the websocket client:
package com.wsclient;
import java.io.IOException;
import java.URI;
import java.URISyntaxException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Main {
public static void main(String[] args) throws Exception {
try {
// open websocket
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("wss://somedomain/ws"));
clientEndPoint.addMessageHandler(
new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String packet) {
System.out.println(packet);
}
}
);
clientEndPoint.sendMessage(payload);
while (true) {
Thread.sleep(1000);
}
and the pom.xml for my websocket client:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0"
xmlns:xsi=";
xsi:schemaLocation=".0.0 .0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>rtw</groupId>
<artifactId>rtw</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<mavenpiler.source>17</mavenpiler.source>
<mavenpiler.target>17</mavenpiler.target>
</properties>
<dependencies>
<!-- .fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.18.2</version>
</dependency>
<!-- .fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.18.2</version>
</dependency>
<!-- .fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<!-- .websocket/jakarta.websocket-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- .google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!-- .websocket/jakarta.websocket-client-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- .glassfish.tyrus.bundles/tyrus-standalone-client -->
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>2.2.0</version>
</dependency>
<!-- .json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20241224</version>
</dependency>
<!-- .mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
</dependency>
</dependencies>
</project>
my goal is to have a websocket server in JAVA that is also called in Main.java in the same manner as my websocket client.
I've searched the internet but all the documentation for the Jakarta repo is unsuccessful so far. There is literally nothing on how to deploy the endpoint. Obviously the endpoint is just a useless file unless its deployed. Below is the Websocket server endpoint.
package com.wsserver;
import java.io.IOException;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
@ServerEndpoint("/ws")
public class WebSocketEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("WebSocket opened: " + session.getId());
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message received: " + message);
try {
session.getBasicRemote().sendText("Echo: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println("WebSocket closed: " + session.getId());
}
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("WebSocket error: " + session.getId());
throwable.printStackTrace();
}
}
Here is the main.java file
package com.wsserver;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
import jakarta.websocket.server.ServerEndpoint;
import jakarta.websocket.server.ServerEndpointConfig;
import java.net.URI;
import java.net.http.WebSocket;
@ServerEndpoint("/ws")
public class Main {
public static void main(String[] args) throws Exception {
ServerEndpointConfig serverEndpoint = ServerEndpointConfig.Builder.create(WebsocketEndpoint.class, "/pathToRoot/").build();
}
}
websocket server pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wsserver</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.18.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.18.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.websocket/jakarta.websocket-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.websocket/jakarta.websocket-client-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.tyrus.bundles/tyrus-standalone-client -->
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20241224</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
</dependency>
</dependencies>
</project>
Main.java seems to sucessfully build the websocket but how would I listen to events? Any insight would be great. Thank you.
here is the working websocket client that I am using to pass data to the websocket server:
package com.wsclient;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import jakarta.websocket.ClientEndpoint;
import jakarta.websocket.CloseReason;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
@ClientEndpoint
public class WebsocketClientEndpoint {
Session userSession = null;
private MessageHandler messageHandler;
public WebsocketClientEndpoint(URI endpointURI) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@OnOpen
public void onOpen(Session userSession) {
System.out.println("opening websocket");
this.userSession = userSession;
}
@OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing websocket");
this.userSession = null;
}
@OnMessage
public void onMessage(String message) throws IOException {
if (this.messageHandler != null) {
this.messageHandler.handleMessage(message);
}
}
@OnMessage
public void onMessage(ByteBuffer bytes) {
System.out.println("Handle byte buffer");
}
public void addMessageHandler(MessageHandler msgHandler) {
this.messageHandler = msgHandler;
}
public void sendMessage(String message) {
this.userSession.getAsyncRemote().sendText(message);
}
public static interface MessageHandler {
public void handleMessage(String message) throws IOException;
}
}
here is Main.java where I call the websocket client:
package com.wsclient;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Main {
public static void main(String[] args) throws Exception {
try {
// open websocket
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("wss://somedomain.com/ws"));
clientEndPoint.addMessageHandler(
new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String packet) {
System.out.println(packet);
}
}
);
clientEndPoint.sendMessage(payload);
while (true) {
Thread.sleep(1000);
}
and the pom.xml for my websocket client:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>rtw</groupId>
<artifactId>rtw</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.18.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.18.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.websocket/jakarta.websocket-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.websocket/jakarta.websocket-client-api -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.tyrus.bundles/tyrus-standalone-client -->
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20241224</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
</dependency>
</dependencies>
</project>
my goal is to have a websocket server in JAVA that is also called in Main.java in the same manner as my websocket client.
Share Improve this question edited Jan 20 at 12:10 BalusC 1.1m376 gold badges3.6k silver badges3.6k bronze badges asked Jan 19 at 7:29 thegillionairethegillionaire 14 bronze badges 2- 1 jakartaee (javaee) are specifications that are useless on their own. The code you write must be executed in a container implementing the corresponding specifications (this is called an EE server). – mr mcwolf Commented Jan 19 at 8:50
- Similar, apparently same author: Implement Java Jakarta webserver with Java.main and not JavaScript – Basil Bourque Commented Jan 19 at 22:14
2 Answers
Reset to default 2WebSocket App Server and Client
ws-server
project tree
ws-server
├── pom.xml
└── src
└── main
└── java
└── com
└── example
└── wsserver
├── Main.java
└── WebSocketServerEndpoint.java
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<version>0.0.1-SNAPSHOT</version>
<artifactId>websocket-serer</artifactId>
<packaging>jar</packaging>
<name>WebSocket Server Application</name>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- Tyrus Server -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-server</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Tyrus Core -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-core</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Grizzly WebSocket -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-container-grizzly-server</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Jakarta WebSocket API -->
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
<build>
<finalName>websocket-server</finalName>
</build>
</project>
WebSocketServerEndpoint.java
package com.example.wsserver;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
@ServerEndpoint("/websocket")
public class WebSocketServerEndpoint {
// Stores all connected client sessions
private static final CopyOnWriteArraySet<Session> sessions = new CopyOnWriteArraySet<>();
// Called when a new client connects
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
System.out.println("WebSocket opened: " + session.getId());
broadcastMessage("Client " + session.getId() + " joined!");
}
// Called when a client message is received
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message received from " + session.getId() +": " + message);
try {
session.getBasicRemote().sendText("Echo: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
// Called when the client disconnects
@OnClose
public void onClose(Session session, CloseReason reason) {
sessions.remove(session);
System.out.println("WebSocket closed: " + session.getId());
broadcastMessage("Client " + session.getId() + " left.");
}
// Called when an error occurs
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("WebSocket error: " + session.getId());
throwable.printStackTrace();
}
// Broadcast a message to all clients
private void broadcastMessage(String message) {
for (Session session : sessions) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Main.java
package com.example.wsserver;
import org.glassfish.tyrus.server.Server;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Server server = new Server("localhost", 8080, "/ws", null, WebSocketServerEndpoint.class);
try {
server.start();
System.out.println("WebSocket server started at ws://localhost:8080/ws/websocket");
System.out.println("Press Enter to stop the server...");
new Scanner(System.in).nextLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
System.out.println("WebSocket server stopped.");
}
}
}
Build and Run
Build
mvn clean package
Download dependencies jar to libs
mvn dependency:copy-dependencies -DoutputDirectory=target/libs
Run
java -cp "target/libs/*:target/websocket-server.jar" com.example.wsserver.Main
Output
org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [0.0.0.0:8080]
org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
org.glassfish.tyrus.server.Server start
INFO: WebSocket Registered apps: URLs all start with ws://localhost:8080
org.glassfish.tyrus.server.Server start
INFO: WebSocket server started.
WebSocket server started at ws://localhost:8080/ws/websocket
Press Enter to stop the server...
WebSocket App
ws-client
project tree
ws-client
├── pom.xml
└── src
└── main
└── java
└── com
└── example
└── wsclient
├── Main.java
└── WebsocketClientEndpoint.java
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<version>0.0.1-SNAPSHOT</version>
<artifactId>websocket-client</artifactId>
<packaging>jar</packaging>
<name>WebSocket Client Application</name>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.tyrus.bundles</groupId>
<artifactId>tyrus-standalone-client</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
<build>
<finalName>websocket-client</finalName>
</build>
</project>
WebsocketClientEndpoint.java
package com.example.wsclient;
import jakarta.websocket.*;
import java.net.URI;
@ClientEndpoint
public class WebsocketClientEndpoint {
private Session session;
public WebsocketClientEndpoint(String serverUri) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
session = container.connectToServer(this, new URI(serverUri));
} catch (Exception e) {
e.printStackTrace();
}
}
@OnMessage
public void onMessage(String message) {
System.out.println("Received from server: " + message);
}
public void sendMessage(String message) {
try {
if (session != null && session.isOpen()) {
session.getAsyncRemote().sendText(message);
} else {
System.out.println("Session is not open");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
try {
if (session != null) {
session.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Main.java
package com.example.wsclient;
public class Main {
public static void main(String[] args) {
String serverUri = "ws://localhost:8080/ws/websocket";
WebsocketClientEndpoint client = new WebsocketClientEndpoint(serverUri);
// Send a message to the server
client.sendMessage("Hello from client!");
// Wait 5 seconds for a response
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Close the client
client.close();
}
}
Build and Run
Build
mvn clean package
Download dependencies jar to libs
mvn dependency:copy-dependencies -DoutputDirectory=target/libs
Run
java -cp "target/libs/*:target/websocket-client.jar" com.example.wsclient.Main
Cleint Output
Received from server: Client 793cb2e6-969a-4167-8493-77db84cee85b joined!
Received from server: Echo: Hello from client!
Server Output
WebSocket opened: 793cb2e6-969a-4167-8493-77db84cee85b
Message received from 793cb2e6-969a-4167-8493-77db84cee85b: Hello from client!
WebSocket closed: 793cb2e6-969a-4167-8493-77db84cee85b
Final App jar
Server
ws-server/target
├── libs
│ ├── grizzly-framework-4.0.0.jar
│ ├── grizzly-http-4.0.0.jar
│ ├── grizzly-http-server-4.0.0.jar
│ ├── jakarta.activation-api-2.1.0.jar
│ ├── jakarta.websocket-api-2.1.0.jar
│ ├── jakarta.websocket-client-api-2.1.0.jar
│ ├── jakarta.xml.bind-api-4.0.0.jar
│ ├── tyrus-client-2.1.0.jar
│ ├── tyrus-container-grizzly-client-2.1.0.jar
│ ├── tyrus-container-grizzly-server-2.1.0.jar
│ ├── tyrus-core-2.1.0.jar
│ ├── tyrus-server-2.1.0.jar
│ └── tyrus-spi-2.1.0.jar
└── websocket-server.jar
Run Commmand:
java -cp "target/libs/*:target/websocket-server.jar" com.example.wsserver.Main
Client
ws-client/target
├── libs
│ ├── jakarta.websocket-client-api-2.1.1.jar
│ └── tyrus-standalone-client-2.1.0.jar
└── websocket-client.jar
Run Commmand:
java -cp "target/libs/*:target/websocket-client.jar" com.example.wsclient.Main
Jakarta EE Example Code:
If you are looking for Jakarta EE compliant sample code, please look in the following locations:
Jakarta EE Tutorial Examples
https://jakarta.ee/learn/docs/jakartaee-tutorial/current/intro/usingexamples/usingexamples.html
The tutorial example codes are located at https://github.com/eclipse-ee4j/jakartaee-examples
Wildfly
https://www.wildfly.org/downloads/
34.0.1.Final or 35.0.0.Final , find Quick Start Source Code -> zip https://github.com/wildfly/quickstart/releases/download/35.0.0.Final/wildfly-35.0.0.Final-quickstarts.zip
WebSocket Samples:
Project Tree
For additional samples, see the GlassFish samples at https://github.com/eclipse-ee4j/glassfish-samples/tree/master/ws/jakartaee9
This example project is modified from the following projects:
https://github.com/eclipse-ee4j/glassfish-samples/tree/master/ws/jakartaee9/websocket/echo
jakartaee10-websocket-echo
├── pom.xml
└── src
└── main
├── java
│ └── org
│ └── glassfish
│ └── samples
│ └── websocket
│ └── echo
│ └── EchoEndpoint.java
└── webapp
├── index.html
└── WEB-INF
└── glassfish-web.xml
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.glassfish-samples</groupId>
<version>6.0-SNAPSHOT</version>
<artifactId>websocket-samples-echo</artifactId>
<packaging>war</packaging>
<name>WebSocket Echo Sample Application</name>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>websocket-echo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>websocket-echo</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>
EchoEndpoint.java
Copy your code into this class.
package org.glassfish.samples.websocket.echo;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Echo endpoint.
*/
@ServerEndpoint("/echo")
public class EchoEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("WebSocket opened: " + session.getId());
}
/**
* Incoming message is represented as parameter and return value is going to be send back to peer.
* </p>
* {@link jakarta.websocket.Session} can be put as a parameter and then you can gain better control of whole
* communication, like sending more than one message, process path parameters, {@link jakarta.websocket.Extension Extensions}
* and sub-protocols and much more.
*
* @param message incoming text message.
* @return outgoing message.
* @see OnMessage
* @see jakarta.websocket.Session
*/
/*
@OnMessage
public String echo(String message) {
return message;
}
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message received: " + message);
try {
session.getBasicRemote().sendText("Echo: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println("WebSocket closed: " + session.getId());
}
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("WebSocket error: " + session.getId());
throwable.printStackTrace();
}
}
index.html
https://github.com/eclipse-ee4j/glassfish-samples/blob/master/ws/jakartaee9/websocket/echo/src/main/webapp/index.html
glassfish-web.xml
https://github.com/eclipse-ee4j/glassfish-samples/blob/master/ws/jakartaee9/websocket/echo/src/main/webapp/WEB-INF/glassfish-web.xml
Build
mvn clean package
output file: websocket-echo.war
jakartaee10-websocket-echo/target/websocket-echo.war
Deploy war files
put websocket-echo.war
into apache-tomcat-10.1.24/webapps
Start Tomcat
In Tomcat directory
cd bin
./startup.sh
Test
Firefox open:
http://localhost:8080/websocket-echo/
input some string
Close Firefox
Check log file
apache-tomcat-10.1.24/logs/catalina.out
your code System.out.println
is output to catalina.out
WebSocket opened: 0
Message received: Hello World - WebSocket!
WebSocket opened: 1
Message received: Hello 1
WebSocket opened: 2
Message received: Hello 2
WebSocket closed: 0
WebSocket closed: 1
WebSocket closed: 2
How to Connect to WebSocket
The webpage for your web application, in this example, is located at src/main/webapp/index.html
.
The index.html
file uses JavaScript to connect to your WebSocket.
<script language="javascript" type="text/javascript">
var wsUri = getRootUri() + "/websocket-echo/echo";
...
UPDATE
I provided another answer. Both WebSocket Client and WebSocket Server use Java Application. -> WebSocket App Server and Client