From 9d8f65fd2956998e181fbe9e593119e4b83eddc0 Mon Sep 17 00:00:00 2001 From: izuna Date: Mon, 25 Nov 2024 17:35:50 +0100 Subject: [PATCH] release: 2.1.1 - Fixes Concurrent Modification on Broadcast - Increase netty version to 4.1.97-Final --- build.gradle.kts | 4 +-- .../ccbluex/netty/http/HttpServerHandler.kt | 2 +- .../http/websocket/WebSocketController.kt | 30 +++++++++++++++---- .../netty/http/websocket/WebSocketHandler.kt | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9c71fdf..e194398 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ val authorName = "ccbluex" val projectUrl = "https://github.com/ccbluex/netty-httpserver" group = "net.ccbluex" -version = "2.1.0" +version = "2.1.1" repositories { mavenCentral() @@ -30,7 +30,7 @@ dependencies { // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core implementation("org.apache.logging.log4j:log4j-core:2.23.1") // https://mvnrepository.com/artifact/io.netty/netty-all - implementation("io.netty:netty-all:4.1.82.Final") + implementation("io.netty:netty-all:4.1.97.Final") // https://mvnrepository.com/artifact/com.google.code.gson/gson implementation("com.google.code.gson:gson:2.10.1") // https://mvnrepository.com/artifact/org.apache.tika/tika-core diff --git a/src/main/kotlin/net/ccbluex/netty/http/HttpServerHandler.kt b/src/main/kotlin/net/ccbluex/netty/http/HttpServerHandler.kt index 297f16d..031659f 100644 --- a/src/main/kotlin/net/ccbluex/netty/http/HttpServerHandler.kt +++ b/src/main/kotlin/net/ccbluex/netty/http/HttpServerHandler.kt @@ -82,7 +82,7 @@ internal class HttpServerHandler(private val server: HttpServer) : ChannelInboun handshaker.handshake(ctx.channel(), msg) } - server.webSocketController.activeContexts += ctx + server.webSocketController.addContext(ctx) } else { val requestContext = RequestContext( msg.method(), diff --git a/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketController.kt b/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketController.kt index 12dcfb6..c822c58 100644 --- a/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketController.kt +++ b/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketController.kt @@ -21,7 +21,7 @@ package net.ccbluex.netty.http.websocket import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.http.websocketx.TextWebSocketFrame -import io.netty.handler.codec.http.websocketx.WebSocketFrame +import java.util.concurrent.CopyOnWriteArrayList /** * Controller for handling websocket connections. @@ -32,7 +32,7 @@ class WebSocketController { * Keeps track of all connected websocket connections to the server. * This is used to broadcast messages to all connected clients. */ - val activeContexts = mutableListOf() + private val activeContexts = CopyOnWriteArrayList() /** * Broadcasts a message to all connected clients. @@ -53,10 +53,30 @@ class WebSocketController { /** * Closes all active contexts. */ - fun closeAll() { - activeContexts.forEach { handlerContext -> - handlerContext.channel().close() + fun disconnect() { + activeContexts.removeIf { handlerContext -> + runCatching { + handlerContext.channel().close().sync() + }.isSuccess } } + /** + * Adds a new context to the list of active contexts. + * + * @param context The context to add. + */ + fun addContext(context: ChannelHandlerContext) { + activeContexts.add(context) + } + + /** + * Removes a context from the list of active contexts. + * + * @param context The context to remove. + */ + fun removeContext(context: ChannelHandlerContext) { + activeContexts.remove(context) + } + } \ No newline at end of file diff --git a/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketHandler.kt b/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketHandler.kt index e165abf..dac654d 100644 --- a/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketHandler.kt +++ b/src/main/kotlin/net/ccbluex/netty/http/websocket/WebSocketHandler.kt @@ -51,7 +51,7 @@ internal class WebSocketHandler(private val server: HttpServer) : ChannelInbound ctx.channel().writeAndFlush(msg.retainedDuplicate()) ctx.channel().close().sync() - server.webSocketController.activeContexts -= ctx + server.webSocketController.removeContext(ctx) logger.debug("WebSocket closed due to ${msg.reasonText()} (${msg.statusCode()})") } else -> logger.error("Unknown WebSocketFrame type: ${msg.javaClass.name}")