https://bz.apache.org/bugzilla/show_bug.cgi?id=59659
Bug ID: 59659
Summary: WsSession leaks (is not GC) if error occurs during the
closing process
Product: Tomcat 8
Version: 8.5.2
Hardware: PC
Status: NEW
Severity: normal
Priority: P2
Component: WebSocket
Assignee: [email protected]
Reporter: [email protected]
Tested on tomee 7.0.0. using tomcat-websocket.jar version 8.5.2.
I found it during the long-term using of WebSockets. After several page
switches and re-openings some WsSessions were not removed even after the
client session finished. It was difficult to reproduce. But here is how to do
it more predictably:
Open the HTML page defined below and several time click reload current page. If
error occurs on Java side (it means that wsError occurs) the WsSession will not
be removed from GC. I tested it mostly with Firefox but it work also on IE 11
etc. JDK 1.7.0_51 64 bit was used.
HTML code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Test</title>
<script>
var ws = null;
var i=0;
var myVar = setInterval(myTimer, 10);
function myTimer() {
if(ws) return;
ws = new WebSocket("ws://localhost:8080/WsMemoryLeak/ws");
console.log("reconnecting " + i++);
ws.onopen = function() {
//ws.send("Message to send");
console.log("onocpen " + i++);
ws.close();
ws = null;
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
console.log("onmessage " + evt.data);
};
ws.onclose = function(){
console.log("onclose");
};
}
window.onbeforeunload = function(){
if(ws) ws.close();
}
</script>
</head>
<body>
<h2>WebSocket test</h2>
</body>
Java Code:
import java.io.IOException;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;
import javax.websocket.MessageHandler;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.tomcat.websocket.WsSession;
@ServerEndpoint(value = "/ws")
public class MyWebsocket {
private static final AtomicInteger count = new AtomicInteger (0);
@OnOpen
public void wsOpen(Session session){
WsSession s = (WsSession) session;
int c = count.incrementAndGet();
System.out.println("WS Opened " + c);
}
@OnError
public void wsError(Session session, Throwable t){
System.out.println("WS Error ");
try {
WsSession s = (WsSession) session;
s.close();
} catch (IOException e) {}
}
@OnClose
public void wsClosed(Session session){
int c = count.decrementAndGet();
System.out.println("WS Closed " + c);
try {
session.close();
} catch (IOException e) {}
}
}
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]