Using WebSocket under Tomcat

Environmental Science

  • tomcat 9
  • JDK8
  • web project with framework

Use

Jar package selection

Because the packages used in the online tutorials are many and miscellaneous, the average person may not see how to use them. In fact, the choice is very simple
  • J2EE: Java EE API with J2EE
  • Others: javax.websocket
  • tomcat: built in websocket API
In fact, the other two packages encapsulate javax.websocket. Because tomcat is used here, tomcat is directly used. The source code behind is from the network

Front end source code

var ws = null;
if('WebSocket' in window) {
    ws = new WebSocket("ws://localhost:8080/xx/websocket");
    ws.onopen = function(){
    };
    ws.onmessage = function(evt){
        console.log(evt);
        var received_msg = evt.data;
    };
    ws.onclose = function(){
        alert("Connection closed..."); 
    };
    ws.onerror = function(){
        alert("An error occurred");
    };
}

Back end code

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/websocket")
public class WebsocketTest {
	//Static variable, used to record the current number of online connections.

    private static AtomicInteger onlineCount = new AtomicInteger(0);

    //The thread safe Set of the concurrent package is used to store the MyWebSocket object corresponding to each client. To realize the communication between the server and a single client, Map can be used for storage, where Key can be the user ID

    protected static CopyOnWriteArraySet<WebsocketTest> webSocketSet = new CopyOnWriteArraySet<WebsocketTest>();

    //A connection session with a client through which data is sent to the client

    private Session session;

    public WebsocketTest() {
        System.out.println(" WebSocket init~~~");
    }
    
    /**
     * Method successfully called for connection establishment
     * @param session  Optional parameters. Session is a connection session with a client, through which data is sent to the client
     */
    @OnOpen
    public void onOpen(Session session){
        this.session = session;
        webSocketSet.add(this);     //Add to set

        addOnlineCount();           //Online data plus 1

        System.out.println("New connection to join! The current number of people online is" + getOnlineCount());
    }

    /**
     * Method of connection close call
     */
    @OnClose
    public void onClose(){
        webSocketSet.remove(this);  //Remove from set

        subOnlineCount();           //Online number minus 1

        System.out.println("There is a connection closed! The current number of people online is" + getOnlineCount());
    }

    /**
     * Method of calling after receiving client message
     * @param message Messages sent by clients
     * @param session Optional parameters
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("Messages from clients:" + message);
        //Mass message

        for(WebsocketTest item: webSocketSet){
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    /**
     * Called when an error occurs
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        System.out.println("An error occurred");
        error.printStackTrace();
    }

    /**
     * This method is different from the above methods. Without annotation, it is a method added according to your own needs.
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException{
        this.session.getBasicRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);

    }

    public static int getOnlineCount() {
        return onlineCount.get();
    }

    public static void addOnlineCount() {
        onlineCount.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineCount.decrementAndGet();
    }

}

Problem analysis

404 error

  • Jar package was not called successfully: tomcat's websocket API package can be configured to Build Path as an external package, and only one websocket package can be used
  • Path intercepted: for example, if the framework intercepts the path automatically, first release the corresponding websocket path rule, and then note that the full path is the localhost:8080 / project name / websocket annotation path

302 error

  • The backend is not defined correctly, and the annotation is not fully effective

Introduction of design pattern

  • It can be simply divided into websocket class and session manager singleton class for managing session, which conforms to the principle of single responsibility
  • It's complex, and it can take the form of an observer model



Keywords: Session Tomcat Java network

Added by mbh23 on Sun, 03 May 2020 09:57:12 +0300