Skip to content

Commit 8d92e20

Browse files
committed
Allowance to stop websocket pinger by config.
1 parent 69c451e commit 8d92e20

File tree

1 file changed

+48
-40
lines changed

1 file changed

+48
-40
lines changed

server/src/main/java/org/red5/net/websocket/WebSocketScopeManager.java

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class WebSocketScopeManager {
3737
// used to ping WS connections
3838
private static final byte[] PING_BYTES = "PING!".getBytes();
3939

40-
// one executor per scope manager
40+
// one executor per scope manager (2 slots - one for pinger, one for notifications)
4141
private ExecutorService executor = Executors.newFixedThreadPool(2);
4242

4343
// future for the ws pinger
@@ -150,50 +150,55 @@ public boolean addWebSocketScope(WebSocketScope webSocketScope) {
150150
if (scopes.putIfAbsent(path, webSocketScope) == null) {
151151
log.info("addWebSocketScope: {}", webSocketScope);
152152
notifyListeners(WebSocketEvent.SCOPE_ADDED, webSocketScope, null);
153-
// ensure the ping future exists, if not spawn it
154-
if (pingFuture == null || pingFuture.isDone()) {
155-
final String appScopeName = appScope != null ? appScope.getName() : "default";
156-
pingFuture = executor.submit(() -> {
157-
final String oldName = Thread.currentThread().getName();
158-
Thread.currentThread().setName(String.format("WebSocketPinger@%s", appScopeName));
159-
do {
160-
scopes.forEach((sName, wsScope) -> {
161-
log.trace("start pinging scope: {}", sName);
162-
wsScope.getConns().forEach(wsConn -> {
163-
try {
164-
// ping connected websocket
165-
if (wsConn.isConnected()) {
166-
log.trace("pinging ws: {} on scope: {}", wsConn.getWsSessionId(), sName);
167-
try {
168-
wsConn.sendPing(PING_BYTES);
169-
} catch (Exception e) {
170-
log.debug("Exception pinging connection: {} connection will be closed", wsConn.getSessionId(), e);
153+
if (websocketPingInterval < 0) {
154+
log.debug("Websocket pinger is disabled");
155+
} else {
156+
// ensure the ping future exists, if not spawn it
157+
if (pingFuture == null || pingFuture.isDone()) {
158+
log.debug("Websocket ping interval: {}", websocketPingInterval);
159+
final String appScopeName = appScope != null ? appScope.getName() : "default";
160+
pingFuture = executor.submit(() -> {
161+
final String oldName = Thread.currentThread().getName();
162+
Thread.currentThread().setName(String.format("WebSocketPinger@%s", appScopeName));
163+
do {
164+
scopes.forEach((sName, wsScope) -> {
165+
log.trace("start pinging scope: {}", sName);
166+
wsScope.getConns().forEach(wsConn -> {
167+
try {
168+
// ping connected websocket
169+
if (wsConn.isConnected()) {
170+
log.trace("pinging ws: {} on scope: {}", wsConn.getWsSessionId(), sName);
171+
try {
172+
wsConn.sendPing(PING_BYTES);
173+
} catch (Exception e) {
174+
log.debug("Exception pinging connection: {} connection will be closed", wsConn.getSessionId(), e);
175+
// if the connection isn't connected, remove them
176+
wsScope.removeConnection(wsConn);
177+
// if the ping fails, consider them gone
178+
wsConn.close();
179+
}
180+
} else {
181+
log.debug("Removing unconnected connection: {} during ping loop", wsConn.getSessionId());
171182
// if the connection isn't connected, remove them
172183
wsScope.removeConnection(wsConn);
173-
// if the ping fails, consider them gone
174-
wsConn.close();
175184
}
176-
} else {
177-
log.debug("Removing unconnected connection: {} during ping loop", wsConn.getSessionId());
178-
// if the connection isn't connected, remove them
179-
wsScope.removeConnection(wsConn);
185+
} catch (Exception e) {
186+
log.warn("Exception in WS pinger", e);
180187
}
181-
} catch (Exception e) {
182-
log.warn("Exception in WS pinger", e);
183-
}
188+
});
189+
log.trace("finished pinging scope: {}", sName);
184190
});
185-
log.trace("finished pinging scope: {}", sName);
186-
});
187-
// sleep for interval
188-
try {
189-
Thread.sleep(websocketPingInterval);
190-
} catch (InterruptedException e) {
191-
}
192-
} while (!scopes.isEmpty());
193-
// reset ping future
194-
pingFuture = null;
195-
Thread.currentThread().setName(oldName);
196-
});
191+
// sleep for interval
192+
try {
193+
Thread.sleep(websocketPingInterval);
194+
} catch (InterruptedException e) {
195+
}
196+
} while (!scopes.isEmpty());
197+
// reset ping future
198+
pingFuture = null;
199+
Thread.currentThread().setName(oldName);
200+
});
201+
}
197202
}
198203
return true;
199204
}
@@ -443,6 +448,9 @@ public void setCopyListeners(boolean copy) {
443448
}
444449

445450
public static void setWebsocketPingInterval(long websocketPingInterval) {
451+
if (websocketPingInterval < 0) {
452+
log.warn("Setting the ping interval to a negative value will disable the internal ping worker");
453+
}
446454
WebSocketScopeManager.websocketPingInterval = websocketPingInterval;
447455
}
448456

0 commit comments

Comments
 (0)