How to keep websocket alive
Asked Answered
S

1

13

I am establishing WebSocket connectivity where the server is built using javax.websocket and the client is in JavaScript.

This code is working fine. But after some time session is closed. I want to keep this session alive.

I have two questions:

  1. If this connection is getting closed because of session idle time out
  2. How to keep this session alive.

Following is the JavaScript code:

var wsUri="ws://localhost/";
var websocket = new WebSocket(wsUri);

var datasocket;
var username;
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
function join() {
    username = textField.value;
    websocket.send(username + " joined");
    console.log("joined");
}

function send_message() {
    websocket.send(username + ": " + textField.value);
}

function onOpen() {
    console.log("connected to url");
    websocket.send("Hello");
    //  writeToScreen("Connected to " + wsUri);
}

function onMessage(evt) {
var res = {};
    console.log("onMessage: " + evt.data);
    if (evt.data.indexOf("joined") != -1) {   
    } else {
        datasocket=evt.data
        //getLatestData();
        res = JSON.parse(event.data);
        $scope.Impact = res["Impact"];
        $scope.Temperature = res["Temperature"];
        $scope.Humidity = res["Humidity"];
    }
}

function onError(evt) {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
} 

function writeToScreen(message) {
//    output.innerHTML += message + "<br>";
}
function onClose(evt)
{
    console.log("Disconnected");
}

And Java code is following:

@javax.websocket.server.ServerEndpoint("/")
public class Endpoint {
     
    private static Queue<Session> queue = new ConcurrentLinkedQueue<Session>();
    static StringBuilder sb = null;
    ByteArrayOutputStream bytes = null;

    
    @OnMessage
    public void onMessage(Session session, String msg) {
        // provided for completeness, in out scenario clients don't send any msg.
        try {   
            // System.out.println("received msg "+msg+" from "+session.getId());
    
           sendAll(msg);  
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
   
    private static void sendAll(String msg) {

        JSONParser parser = new JSONParser();
        Object obj = null ;

        try {
            obj = parser.parse(msg);
        } catch (ParseException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        JSONObject jsonObject = (JSONObject) obj;
        
        if (sb == null) {
            sb = new StringBuilder();
        }
        sb.append(jsonObject.toString());
     
        //     System.out.println(jsonObject.toJSONString());
        try {
            /* Send the new rate to all open WebSocket sessions */  
            ArrayList<Session > closedSessions= new ArrayList<>();
            for (Session session : queue) {
                if(!session.isOpen()) {
                     System.err.println("Closed session: "+session.getId());
                     closedSessions.add(session);
                }
                else {
                    session.getBasicRemote().sendText(msg);
                }
            }
            queue.removeAll(closedSessions);
            //     System.out.println("Sending "+msg+" to "+queue.size()+" clients");
        } catch (Throwable e) {
            e.printStackTrace();
        }
        
        sb = null;
        
    }
    
    @OnOpen
    public void open(Session session) {
         queue.add(session);
         System.out.println("New session opened: "+session.getId());
    }
     
    @OnError
    public void error(Session session, Throwable t) {
        queue.remove(session);
        System.err.println("Error on session "+session.getId());  
    }
    
    @OnClose
    public void closedConnection(Session session) { 
        queue.remove(session);
        System.out.println("session closed: "+session.getId());
    }
    
}
Shaylyn answered 14/3, 2017 at 7:5 Comment(3)
To keep the session active, use a timer to send data periodically. The WebSocket protocol defines a ping/pong mechanism, but the WebSocket API in HTML5 does not expose direct access to that mechanism, though web browsers may handle it internally in their WebSocket implementation.Chuu
Right now I am sending some value using websocket.send periodically but if it is a proper way? Is there any idle timeout or something?Shaylyn
you can configure the timeout of a websocket session: docs.oracle.com/javaee/7/api/javax/websocket/… but the client can be guilty as well (connectivity lost, application killed if on mobile, etc)Abridge
A
1

you can disable the timeout in the server using a negative number in the IdleTimout

session.setMaxIdleTimeout(-1)

Set the non-zero number of milliseconds before this session will be closed by the container if it is inactive, ie no messages are either sent or received. A value that is 0 or negative indicates the session will never timeout due to inactivity.

Adaadabel answered 6/11, 2022 at 1:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.