From e934d254618152aa6c8b43eff8499abfc804afef Mon Sep 17 00:00:00 2001 From: Robert Schlabbach Date: Thu, 4 Dec 2025 09:54:41 +0100 Subject: [PATCH 1/2] Add WebSocket Compression Support OCPP 2.0.1 requires CSMS and Local Controllers to support RFC 7692 WebSocket compression, and recommends it for Charging Stations using mobile data connections. This feature was not implemented yet. Add the WEBSOCKET_COMPRESSION_SUPPORT boolean to JSONConfiguration, enabled by default for the server and disabled by default for the client. Bump the WebSocket library dependency from version 1.5.3 to 1.6.0, since the PerMessageDeflateExtension was broken in older versions. --- OCPP-J/build.gradle | 2 +- OCPP-J/pom.xml | 2 +- .../eu/chargetime/ocpp/JSONConfiguration.java | 1 + .../json-client-implementation/pom.xml | 2 +- ocpp-v1_6-example/json_server_example/pom.xml | 2 +- ocpp-v1_6/build.gradle | 2 +- ocpp-v1_6/pom.xml | 2 +- ocpp-v2/build.gradle | 2 +- ocpp-v2/pom.xml | 2 +- .../chargetime/ocpp/MultiProtocolJSONClient.java | 15 +++++++++++++-- .../chargetime/ocpp/MultiProtocolJSONServer.java | 14 +++++++++++++- ocpp-v2_0/build.gradle | 2 +- ocpp-v2_0/pom.xml | 2 +- 13 files changed, 37 insertions(+), 13 deletions(-) diff --git a/OCPP-J/build.gradle b/OCPP-J/build.gradle index c2fcadd2..be3c889a 100644 --- a/OCPP-J/build.gradle +++ b/OCPP-J/build.gradle @@ -5,7 +5,7 @@ dependencies { compile project(':common') compile 'com.google.code.gson:gson:2.8.9' - compile 'org.java-websocket:Java-WebSocket:1.5.3' + compile 'org.java-websocket:Java-WebSocket:1.6.0' testCompile 'junit:junit:4.13.2' testCompile 'org.mockito:mockito-core:4.11.0' testCompile 'org.hamcrest:hamcrest-core:1.3' diff --git a/OCPP-J/pom.xml b/OCPP-J/pom.xml index 872916fb..8647501d 100644 --- a/OCPP-J/pom.xml +++ b/OCPP-J/pom.xml @@ -61,7 +61,7 @@ org.java-websocket Java-WebSocket - 1.5.4 + 1.6.0 junit diff --git a/OCPP-J/src/main/java/eu/chargetime/ocpp/JSONConfiguration.java b/OCPP-J/src/main/java/eu/chargetime/ocpp/JSONConfiguration.java index 78255043..f5da6146 100644 --- a/OCPP-J/src/main/java/eu/chargetime/ocpp/JSONConfiguration.java +++ b/OCPP-J/src/main/java/eu/chargetime/ocpp/JSONConfiguration.java @@ -38,6 +38,7 @@ public class JSONConfiguration { public static final String PASSWORD_PARAMETER = "PASSWORD"; public static final String CONNECT_NON_BLOCKING_PARAMETER = "CONNECT_NON_BLOCKING"; public static final String CONNECT_TIMEOUT_IN_MS_PARAMETER = "CONNECT_TIMEOUT_IN_MS"; + public static final String WEBSOCKET_COMPRESSION_SUPPORT = "WEBSOCKET_COMPRESSION_SUPPORT"; public static final String WEBSOCKET_WORKER_COUNT = "WEBSOCKET_WORKER_COUNT"; public static final String HTTP_HEALTH_CHECK_ENABLED = "HTTP_HEALTH_CHECK_ENABLED"; public static final String OCPPJ_CP_MIN_PASSWORD_LENGTH = "OCPPJ_CP_MIN_PASSWORD_LENGTH"; diff --git a/ocpp-v1_6-example/json-client-implementation/pom.xml b/ocpp-v1_6-example/json-client-implementation/pom.xml index c4b9e15b..d3b56947 100644 --- a/ocpp-v1_6-example/json-client-implementation/pom.xml +++ b/ocpp-v1_6-example/json-client-implementation/pom.xml @@ -36,7 +36,7 @@ org.java-websocket Java-WebSocket - 1.5.3 + 1.6.0 com.google.code.gson diff --git a/ocpp-v1_6-example/json_server_example/pom.xml b/ocpp-v1_6-example/json_server_example/pom.xml index 1d3c6ec9..69dd3f17 100644 --- a/ocpp-v1_6-example/json_server_example/pom.xml +++ b/ocpp-v1_6-example/json_server_example/pom.xml @@ -36,7 +36,7 @@ org.java-websocket Java-WebSocket - 1.5.3 + 1.6.0 com.google.code.gson diff --git a/ocpp-v1_6/build.gradle b/ocpp-v1_6/build.gradle index 6d7b823e..b287c9c1 100644 --- a/ocpp-v1_6/build.gradle +++ b/ocpp-v1_6/build.gradle @@ -5,7 +5,7 @@ dependencies { compile project(':common') compile project(':OCPP-J') - compile 'org.java-websocket:Java-WebSocket:1.5.3' + compile 'org.java-websocket:Java-WebSocket:1.6.0' compile group: 'javax.xml.soap', name: 'javax.xml.soap-api', version: '1.4.0' testCompile 'junit:junit:4.13.2' diff --git a/ocpp-v1_6/pom.xml b/ocpp-v1_6/pom.xml index 95c7babc..698bed21 100644 --- a/ocpp-v1_6/pom.xml +++ b/ocpp-v1_6/pom.xml @@ -60,7 +60,7 @@ org.java-websocket Java-WebSocket - 1.5.4 + 1.6.0 junit diff --git a/ocpp-v2/build.gradle b/ocpp-v2/build.gradle index 666c8546..f5e8811e 100644 --- a/ocpp-v2/build.gradle +++ b/ocpp-v2/build.gradle @@ -7,7 +7,7 @@ dependencies { compile project(':OCPP-J') compile project(':v1_6') compile 'com.google.code.findbugs:jsr305:3.0.1' - compile 'org.java-websocket:Java-WebSocket:1.5.3' + compile 'org.java-websocket:Java-WebSocket:1.6.0' testCompile 'junit:junit:4.13.2' testCompile 'org.mockito:mockito-core:4.11.0' testCompile 'org.hamcrest:hamcrest-core:1.3' diff --git a/ocpp-v2/pom.xml b/ocpp-v2/pom.xml index ec80d129..db1aa97e 100644 --- a/ocpp-v2/pom.xml +++ b/ocpp-v2/pom.xml @@ -70,7 +70,7 @@ org.java-websocket Java-WebSocket - 1.5.4 + 1.6.0 junit diff --git a/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONClient.java b/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONClient.java index 5a18100f..1ca525a1 100644 --- a/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONClient.java +++ b/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONClient.java @@ -35,14 +35,16 @@ import eu.chargetime.ocpp.wss.WssSocketBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletionStage; +import java.util.zip.Deflater; import javax.annotation.Nullable; import javax.net.ssl.SSLContext; import org.java_websocket.drafts.Draft; import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.extensions.IExtension; +import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension; import org.java_websocket.protocols.IProtocol; import org.java_websocket.protocols.Protocol; import org.slf4j.Logger; @@ -88,11 +90,20 @@ public MultiProtocolJSONClient( List protocolVersions, String identity, JSONConfiguration configuration) { this.identity = identity; featureRepository = new MultiProtocolFeatureRepository(protocolVersions); + List inputExtensions = new ArrayList<>(); + if (configuration.getParameter(JSONConfiguration.WEBSOCKET_COMPRESSION_SUPPORT, false)) { + PerMessageDeflateExtension perMessageDeflateExtension = + new PerMessageDeflateExtension(Deflater.BEST_COMPRESSION); + perMessageDeflateExtension.setThreshold(0); + perMessageDeflateExtension.setServerNoContextTakeover(false); + perMessageDeflateExtension.setClientNoContextTakeover(false); + inputExtensions.add(perMessageDeflateExtension); + } List inputProtocols = new ArrayList<>(protocolVersions.size()); for (ProtocolVersion protocolVersion : protocolVersions) { inputProtocols.add(new Protocol(protocolVersion.getSubProtocolName())); } - Draft draft = new Draft_6455(Collections.emptyList(), inputProtocols); + Draft draft = new Draft_6455(inputExtensions, inputProtocols); transmitter = new MultiProtocolWebSocketTransmitter(featureRepository, configuration, draft); JSONCommunicator communicator = new JSONCommunicator(transmitter, false); ISessionFactory sessionFactory = new MultiProtocolSessionFactory(featureRepository); diff --git a/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java b/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java index 282a6e12..2008abf1 100644 --- a/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java +++ b/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java @@ -39,9 +39,12 @@ of this software and associated documentation files (the "Software"), to deal import java.util.List; import java.util.UUID; import java.util.concurrent.CompletionStage; +import java.util.zip.Deflater; import javax.net.ssl.SSLContext; import org.java_websocket.drafts.Draft; import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.extensions.IExtension; +import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension; import org.java_websocket.protocols.IProtocol; import org.java_websocket.protocols.Protocol; import org.slf4j.Logger; @@ -67,11 +70,20 @@ public MultiProtocolJSONServer( featureRepository = new MultiProtocolFeatureRepository(protocolVersions); MultiProtocolSessionFactory sessionFactory = new MultiProtocolSessionFactory(featureRepository); + List extensions = new ArrayList<>(); + if (configuration.getParameter(JSONConfiguration.WEBSOCKET_COMPRESSION_SUPPORT, true)) { + PerMessageDeflateExtension perMessageDeflateExtension = + new PerMessageDeflateExtension(Deflater.BEST_COMPRESSION); + perMessageDeflateExtension.setThreshold(0); + perMessageDeflateExtension.setServerNoContextTakeover(false); + perMessageDeflateExtension.setClientNoContextTakeover(false); + extensions.add(perMessageDeflateExtension); + } List protocols = new ArrayList<>(protocolVersions.size()); for (ProtocolVersion protocolVersion : protocolVersions) { protocols.add(new Protocol(protocolVersion.getSubProtocolName())); } - Draft draft = new Draft_6455(Collections.emptyList(), protocols); + Draft draft = new Draft_6455(extensions, protocols); if (configuration.getParameter(JSONConfiguration.HTTP_HEALTH_CHECK_ENABLED, true)) { logger.info("JSONServer with HttpHealthCheckDraft"); diff --git a/ocpp-v2_0/build.gradle b/ocpp-v2_0/build.gradle index 2d831fe5..d3ef9007 100644 --- a/ocpp-v2_0/build.gradle +++ b/ocpp-v2_0/build.gradle @@ -5,7 +5,7 @@ dependencies { compile project(':common') compile project(':OCPP-J') - compile 'org.java-websocket:Java-WebSocket:1.5.3' + compile 'org.java-websocket:Java-WebSocket:1.6.0' testCompile 'junit:junit:4.13.2' testCompile 'org.mockito:mockito-core:4.11.0' testCompile 'org.hamcrest:hamcrest-core:1.3' diff --git a/ocpp-v2_0/pom.xml b/ocpp-v2_0/pom.xml index 344e10d0..cb94d9dd 100644 --- a/ocpp-v2_0/pom.xml +++ b/ocpp-v2_0/pom.xml @@ -60,7 +60,7 @@ org.java-websocket Java-WebSocket - 1.5.4 + 1.6.0 junit From a240984c66357876de5e88050528f84bf7ec0f8e Mon Sep 17 00:00:00 2001 From: Robert Schlabbach Date: Thu, 4 Dec 2025 10:30:41 +0100 Subject: [PATCH 2/2] Remove no longer needed import from MultiProtocolJSONServer --- .../main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java b/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java index 2008abf1..343027fc 100644 --- a/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java +++ b/ocpp-v2/src/main/java/eu/chargetime/ocpp/MultiProtocolJSONServer.java @@ -35,7 +35,6 @@ of this software and associated documentation files (the "Software"), to deal import eu.chargetime.ocpp.wss.WssFactoryBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletionStage;