Chapter 3. Deploying WebSocket Endpoints

Deploying WebSocket endpoints can be done in two ways. Either deploying via putting the endpoint in the WAR file, or using the ServerContainer methods to deploy the programmatic endpoint in the deployment phase.

3.1. Deploying Endpoints as a WAR file

The classes that are scanned for in WAR are the following ones:

  • Classes that implement the jakarta.websocket.ServerApplicationConfig.

  • Classes annotated with jakarta.websocket.server.ServerEndpoint.

  • Classes that extend jakarta.websocket.Endpoint.

3.1.1. Deployment Algorithm

  1. If one or more classes implementing ServerApplicationConfiguration are present in the WAR file, Tyrus deploys endpoints provided by all of these classes. Tyrus doesn't deploy any other classes present in the WAR (annotated by jakarta.websocket.server.ServerEndpoint or extending jakarta.websocket.Endpoint).
  2. If no class implementing ServerApplicationConfiguration is present, Tyrus deploys all classes annotated with @ServerEndpoint or extending Endpoint present in the WAR.

Let's have the following classes in the WAR:

Example 3.1. Deployment of WAR containing several classes extending jakarta.websocket.server.ServerApplicationConfig

public class MyApplicationConfigOne implements ServerApplicationConfig {
    public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses);
        Set<Class<? extends Endpoint>> s = new HashSet<Class<? extends Endpoint>>;
        s.add(ProgrammaticEndpointOne.class);
        return s;
    }

    public Set<Class> getAnnotatedEndpointClasses(Set<Class<?>> scanned);
       Set<Class<?>> s = new HashSet<Class<?>>;
        s.add(AnnotatedEndpointOne.class);
        return s;
    }
}

public class MyApplicationConfigTwo implements ServerApplicationConfig {
    public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses);
        Set<Class<? extends Endpoint>> s = new HashSet<Class<? extends Endpoint>>;
        s.add(ProgrammaticEndpointTwo.class);
    return s;
}

public Set<Class> getAnnotatedEndpointClasses(Set<Class<?>> scanned);
    Set<Class<?>> s = new HashSet<Class<?>>;
        s.add(AnnotatedEndpointTwo.class);
        return s;
    }
}

@ServerEndpoint(value = "/annotatedone")
public class AnnotatedEndpointOne {
    ...
}

@ServerEndpoint(value = "/annotatedtwo")
    public class AnnotatedEndpointTwo {
    ...
}

@ServerEndpoint(value = "/annotatedthree")
public class AnnotatedEndpointThree {
    ...
}

public class ProgrammaticEndpointOne extends Endpoint {
    ...
}

public class ProgrammaticEndpointTwo extends Endpoint {
    ...
}

public class ProgrammaticEndpointThree extends Endpoint {
    ...
}


According to the deployment algorithm classes AnnotatedEndpointOne, AnnotatedEndpointTwo, ProgrammaticEndpointOne and ProgrammaticEndpointTwo will be deployed. AnnotatedEndpointThree and ProgrammaticEndpointThree will not be deployed, as these are not returned by the respective methods of MyApplicationConfigOne nor MyApplicationConfigTwo.

3.2. Deploying endpoints via jakarta.websocket.server.ServerContainer

Endpoints may be deployed using jakarta.websocket.server.ServerContainer during the application initialization phase. For websocket enabled web containers, developers may obtain a reference to the ServerContainer instance by retrieving it as an attribute named jakarta.websocket.server.ServerContainer on the ServletContext, see the following example for annotated endpoint:

Example 3.2. Deployment of Annotated Endpoint Using ServerContainer

@WebListener
@ServerEndpoint("/annotated")
public class MyServletContextListenerAnnotated implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        final ServerContainer serverContainer = (ServerContainer) servletContextEvent.getServletContext()
                                                    .getAttribute("jakarta.websocket.server.ServerContainer");

        try {
            serverContainer.addEndpoint(MyServletContextListenerAnnotated.class);
        } catch (DeploymentException e) {
            e.printStackTrace();
        }
    }

    @OnMessage
    public String onMessage(String message) {
        return message;
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}