[prev in list] [next in list] [prev in thread] [next in thread] 

List:       tomcat-user
Subject:    Tomcat 9.0.8 asynchronous websocket issue
From:       Austin Bookhart <austin.bookhart () hannonhill ! com>
Date:       2019-02-28 20:29:03
Message-ID: CAJJifsJcf0jkh_FCw-eBVo3zrAMB+xsmb2FjkCV5zf0VLFqcQw () mail ! gmail ! com
[Download RAW message or body]

Hi,

I have a question regarding an asynchronous websocket implementation
we have in our application. We have run into issues where on a rare
occasion the websocket endpoint will become unusable due to what seems
to be a thread holding onto resources and not releasing them. Below is
the main structure of our endpoint. Some parts have been removed or
commented out, but it gets the basic structure across.

We call "sendMessageToUser" in order to send a message to a client's
browser. The issue that we have seen is if we breakpoint at the line
that waits for the future to resolve, "future.get()", and reload the
current client's browser, the endpoint becomes unusable where no
messages can be sent or received any longer. Only a restart resolves
the issue. We wanted to find out if our implementation of the
asynchronous remote and future setup is correct or if there is a more
appropriate use of the API?

Appreciate any help you can provide.
Thanks,
Austin

@ServerEndpoint(value = "/websocket", configurator =
GetHttpSessionConfigurator.class)
public class WebSocketEndpoint
{
    private static final Map<Session, SessionDetails> clients =
Collections.synchronizedMap(new HashMap<Session, SessionDetails>());
    private static Future<Void> future = null;

    public static void sendMessageToUser(String username,
WebSocketMessage message)
    {
        synchronized (clients)
        {
            clients.keySet().stream()
                    .filter(client ->
username.equals(clients.get(client).username))
                    .forEach(client -> sendMessage(client, message));
        }
    }

    private static synchronized void sendMessage(Session client,
WebSocketMessage message)
    {
        try
        {
            if (future == null)
                LOG.debug("Sending very first WebSocket message");
            else
            {
                // Before we send the next message, we have to wait
for the previous message to complete
                LOG.debug("Waiting until last WebSocket message is being sent");
                future.get();

                LOG.debug("Last WebSocket message is not longer being
sent. Sending a new message.");
            }


            // Send the message and store the Future for the next call
            future =
client.getAsyncRemote().sendText(message.getJSONObject().toString());
        }
        catch (Exception e)
        {
            LOG.debug("An error occurred when sending a web socket
message to client " + client, e);
        }
    }

    @OnOpen
    public void onOpen(Session client, EndpointConfig config)
    {
        //Construct SessionDetails information
        clients.put(client, new SessionDetails(..));
    }

    @OnClose
    public void onClose(Session client)
    {
        clients.remove(client);
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic