I have problem to implement websocket with tomcat embedded .
this dependencies i used :
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>11.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>11.0.4</version>
</dependency>
</dependencies>
this is my example code :
public class MainClass {
private static final String contextPath = "";
private static final String baseDir = "/tmp/tomcat";
public static void main(String[] args) throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setHostname("0.0.0.0");
tomcat.setPort(8080);
tomcat.setBaseDir(baseDir);
// Add the WebSocket initializer
Context context = tomcat.addContext(contextPath, baseDir);
context.addServletContainerInitializer(new WsSci(), null);
// register servlet
tomcat.addServlet(contextPath, "sample", new SampleServlet());
context.addServletMappingDecoded("/sample", "sample");
// Start the server
tomcat.start();
// Retrieve the ServerContainer and register the WebSocket endpoint
ServerContainer serverContainer = (ServerContainer) context.getServletContext()
.getAttribute("jakarta.websocket.server.ServerContainer");
ServerEndpointConfig config = ServerEndpointConfig.Builder.create(SampleWebSocket.class, "/ws").build();
serverContainer.addEndpoint(config);
// Add the connector and await
tomcat.getService().addConnector(tomcat.getConnector());
tomcat.getServer().await();
}
}
this is SampleWebSocket :
public class SampleWebSocket extends Endpoint implements MessageHandler.Whole<String> {
private Session session;
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
this.session = session;
}
@Override
public void onMessage(String s) {
try {
System.out.println("Receive : " + s);
session.getBasicRemote().sendText(LocalDateTime.now() + " Server response");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
I test that code with linux websocat
command :
> websocat ws://localhost:8080/ws
websocat: WebSocketError: WebSocketError: Received unexpected status code (404 Not Found)
I can not found any example code or documentation about that ! How to use annotated classes ?
ws-server-st
├── pom.xml
├── README.txt
└── src
└── main
└── java
└── com
└── example
└── wsserver
├── Main.java
└── SampleWebSocket.java
<?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>com.example</groupId>
<artifactId>websocket-server-jakarta-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>tomcat Examples :: Embedded :: WebSocket Server with Jakarta EE API</name>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<tomcatVersion>11.0.4</tomcatVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcatVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcatVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcatVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcatVersion}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>websocket-server</finalName>
</build>
</project>
package com.example.wsserver;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.websocket.server.WsSci;
import java.io.File;
import java.util.HashSet;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.getConnector().setProperty("address", "0.0.0.0");
var context = tomcat.addWebapp("", new File(".").getAbsolutePath());
context.addServletContainerInitializer(new WsSci(), new HashSet<>(List.of(SampleWebSocket.class)));
tomcat.start();
System.out.println("Tomcat startup is completed, listening to port 8080");
tomcat.getServer().await();
}
}
package com.example.wsserver;
import jakarta.websocket.EndpointConfig;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalDateTime;
@ServerEndpoint("/ws")
public class SampleWebSocket {
private Session session;
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) {
this.session = session;
}
@OnMessage
public void onMessage(String s) {
try {
System.out.println("Receive : " + s);
session.getBasicRemote().sendText(LocalDateTime.now() + " Server response");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
mvn clean package
mvn dependency:copy-dependencies -DoutputDirectory=target/libs
java -cp "target/libs/*:target/websocket-server.jar" com.example.wsserver.Main
$ ./websocat.x86_64-unknown-linux-musl ws://localhost:8080/ws
Hello
2025-03-04T15:04:11.813977680 Server response
World
2025-03-04T15:04:14.734585249 Server response
Receive : Hello
Receive : World
Check if there is any Java program running, and see if there is any Java program listening to port 8080.
ss -tulnp | grep java
$ ss -tulnp | grep java
tcp LISTEN 0 100 *:8080 *:* users:(("java",pid=47247,fd=13))
lsof -i :8080
$ lsof -i :8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 47247 demo 13u IPv6 164794 0t0 TCP *:http-alt (LISTEN)