diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 439755f9..8531e775 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,24 +11,38 @@ jobs:
runs-on: ubuntu-latest
strategy:
+ fail-fast: false
matrix:
java: [7, 8, 11]
steps:
- uses: actions/checkout@v2
+
+ - name: Install Maven 3.8.x (instead of 3.9.x)
+ run: |
+ MAVEN_VERSION=3.8.9
+ wget https://downloads.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz
+ tar xzvf apache-maven-$MAVEN_VERSION-bin.tar.gz
+ sudo mv apache-maven-$MAVEN_VERSION /opt/maven
+ sudo rm -f /usr/bin/mvn # Remove existing symbolic link if it exists
+ sudo ln -s /opt/maven/bin/mvn /usr/bin/mvn # Create new symbolic link
+
- name: Setup java
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.java }}
+
- name: Cache Maven packages
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
- path: ~/.m2
+ path: ~/.m2/repository
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
+
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 14.x
+
- name: Run the Maven verify phase
run: mvn verify -Dgpg.skip=true
diff --git a/History.md b/History.md
index 18e4f07b..1366aaec 100644
--- a/History.md
+++ b/History.md
@@ -1,4 +1,38 @@
+2.1.2 / 2025-02-18
+==================
+
+### Bug Fixes
+
+- make acks thread safe ([4f45e3c](https://github.com/socketio/socket.io-client-java/commit/4f45e3c1271554da5b3457f447a6d6b060ef5ffd))
+
+
+
+2.1.1 / 2024-07-10
+==================
+
+### Bug Fixes
+
+* discard acknowledgements upon disconnection ([54645ec](https://github.com/socketio/socket.io-client-java/commit/54645ece2cd132f3e305b80904e1fc38bd41c4f9))
+* make sendBuffer thread safe ([#769](https://github.com/socketio/socket.io-client-java/issues/769)) ([b00ae8e](https://github.com/socketio/socket.io-client-java/commit/b00ae8eec1ef0aa5094fca7fad918a437603eb12))
+
+
+
+1.0.2 / 2022-07-11
+==================
+
+From the "1.x" branch.
+
+### Bug Fixes
+
+* ensure buffered events are sent in order ([8bd35da](https://github.com/socketio/socket.io-client-java/commit/8bd35da19c1314318fe122876d22e30ae3673ff9))
+* ensure randomizationFactor is always between 0 and 1 ([cb966d5](https://github.com/socketio/socket.io-client-java/commit/cb966d5a64790c0584ad97cf55c205cae8bd1287))
+* ensure the payload format is valid ([8664499](https://github.com/socketio/socket.io-client-java/commit/8664499b6f31154f49783531f778dac5387b766b))
+* fix usage with ws:// scheme ([e57160a](https://github.com/socketio/socket.io-client-java/commit/e57160a00ca1fbb38396effdbc87eb10d6759a51))
+* increase the readTimeout value of the default OkHttpClient ([2d87497](https://github.com/socketio/engine.io-client-java/commit/2d874971c2428a7a444b3a33afe66aedcdce3a96)) (from `engine.io-client`)
+
+
+
2.1.0 / 2022-07-10
==================
diff --git a/pom.xml b/pom.xml
index e6ff6051..4636cb1b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
io.socket
socket.io-client
- 2.1.0
+ 2.1.3-SNAPSHOT
jar
socket.io-client
Socket.IO Client Library for Java
@@ -30,7 +30,7 @@
https://github.com/socketio/socket.io-client-java
scm:git:https://github.com/socketio/socket.io-client-java.git
scm:git:https://github.com/socketio/socket.io-client-java.git
- socket.io-client-2.1.0
+ HEAD
diff --git a/src/main/java/io/socket/client/Manager.java b/src/main/java/io/socket/client/Manager.java
index a3c5f19e..04198998 100644
--- a/src/main/java/io/socket/client/Manager.java
+++ b/src/main/java/io/socket/client/Manager.java
@@ -72,20 +72,20 @@ public class Manager extends Emitter {
private long _reconnectionDelay;
private long _reconnectionDelayMax;
private double _randomizationFactor;
- private Backoff backoff;
+ private final Backoff backoff;
private long _timeout;
- private URI uri;
- private List packetBuffer;
- private Queue subs;
- private Options opts;
+ private final URI uri;
+ private final List packetBuffer = new ArrayList<>();
+ private final Queue subs = new LinkedList<>();;
+ private final Options opts;
/*package*/ io.socket.engineio.client.Socket engine;
- private Parser.Encoder encoder;
- private Parser.Decoder decoder;
+ private final Parser.Encoder encoder;
+ private final Parser.Decoder decoder;
/**
* This HashMap can be accessed from outside of EventThread.
*/
- /*package*/ ConcurrentHashMap nsps;
+ /*package*/ final Map nsps = new ConcurrentHashMap<>();
public Manager() {
@@ -114,8 +114,6 @@ public Manager(URI uri, Options opts) {
opts.callFactory = defaultCallFactory;
}
this.opts = opts;
- this.nsps = new ConcurrentHashMap<>();
- this.subs = new LinkedList<>();
this.reconnection(opts.reconnection);
this.reconnectionAttempts(opts.reconnectionAttempts != 0 ? opts.reconnectionAttempts : Integer.MAX_VALUE);
this.reconnectionDelay(opts.reconnectionDelay != 0 ? opts.reconnectionDelay : 1000);
@@ -129,7 +127,6 @@ public Manager(URI uri, Options opts) {
this.readyState = ReadyState.CLOSED;
this.uri = uri;
this.encoding = false;
- this.packetBuffer = new ArrayList<>();
this.encoder = opts.encoder != null ? opts.encoder : new IOParser.Encoder();
this.decoder = opts.decoder != null ? opts.decoder : new IOParser.Decoder();
}
diff --git a/src/main/java/io/socket/client/Socket.java b/src/main/java/io/socket/client/Socket.java
index 49bc3784..2227a30d 100644
--- a/src/main/java/io/socket/client/Socket.java
+++ b/src/main/java/io/socket/client/Socket.java
@@ -9,6 +9,7 @@
import org.json.JSONObject;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -56,23 +57,21 @@ public class Socket extends Emitter {
private volatile boolean connected;
private int ids;
- private String nsp;
- private Manager io;
- private Map auth;
- private Map acks = new HashMap<>();
+ private final String nsp;
+ private final Manager io;
+ private final Map auth;
+ private final Map acks = new ConcurrentHashMap<>();
private Queue subs;
- private final Queue> receiveBuffer = new LinkedList<>();
- private final Queue> sendBuffer = new LinkedList<>();
+ private final Queue> receiveBuffer = new ConcurrentLinkedQueue<>();
+ private final Queue> sendBuffer = new ConcurrentLinkedQueue<>();
- private ConcurrentLinkedQueue onAnyIncomingListeners = new ConcurrentLinkedQueue<>();
- private ConcurrentLinkedQueue onAnyOutgoingListeners = new ConcurrentLinkedQueue<>();
+ private final ConcurrentLinkedQueue onAnyIncomingListeners = new ConcurrentLinkedQueue<>();
+ private final ConcurrentLinkedQueue onAnyOutgoingListeners = new ConcurrentLinkedQueue<>();
public Socket(Manager io, String nsp, Manager.Options opts) {
this.io = io;
this.nsp = nsp;
- if (opts != null) {
- this.auth = opts.auth;
- }
+ this.auth = opts != null ? opts.auth : null;
}
private void subEvents() {
@@ -283,6 +282,21 @@ private void onclose(String reason) {
this.connected = false;
this.id = null;
super.emit(EVENT_DISCONNECT, reason);
+ this.clearAcks();
+ }
+
+ /**
+ * Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from
+ * the server.
+ */
+ private void clearAcks() {
+ for (Ack ack : this.acks.values()) {
+ if (ack instanceof AckWithTimeout) {
+ ((AckWithTimeout) ack).onTimeout();
+ }
+ // note: basic Ack objects have no way to report an error, so they are simply ignored here
+ }
+ this.acks.clear();
}
private void onpacket(Packet> packet) {
@@ -301,13 +315,7 @@ private void onpacket(Packet> packet) {
break;
}
- case Parser.EVENT: {
- @SuppressWarnings("unchecked")
- Packet p = (Packet) packet;
- this.onevent(p);
- break;
- }
-
+ case Parser.EVENT:
case Parser.BINARY_EVENT: {
@SuppressWarnings("unchecked")
Packet p = (Packet) packet;
@@ -315,13 +323,7 @@ private void onpacket(Packet> packet) {
break;
}
- case Parser.ACK: {
- @SuppressWarnings("unchecked")
- Packet p = (Packet) packet;
- this.onack(p);
- break;
- }
-
+ case Parser.ACK:
case Parser.BINARY_ACK: {
@SuppressWarnings("unchecked")
Packet p = (Packet) packet;
@@ -448,12 +450,6 @@ private void destroy() {
this.subs = null;
}
- for (Ack ack : acks.values()) {
- if (ack instanceof AckWithTimeout) {
- ((AckWithTimeout) ack).cancelTimer();
- }
- }
-
this.io.destroy();
}
diff --git a/src/site/markdown/android.md b/src/site/markdown/android.md
index a33b2f92..be5c7906 100644
--- a/src/site/markdown/android.md
+++ b/src/site/markdown/android.md
@@ -57,3 +57,27 @@ Starting with Android 9 (API level 28) you need to explicitly allow cleartext tr
```
Reference: https://developer.android.com/training/articles/security-config
+
+## How to run unit tests in Android Studio?
+
+Local unit tests are tests that run on your machine's local Java Virtual Machine.
+
+Reference: https://developer.android.com/studio/test/test-in-android-studio
+
+Since they run on your machine, the JSON library must be manually included for the tests (because it is not provided by the Android runtime):
+
+`build.gradle`
+
+```
+dependencies {
+ implementation ('io.socket:socket.io-client:2.0.1') {
+ exclude group: 'org.json', module: 'json'
+ }
+
+ testImplementation 'org.json:json:20090211'
+
+ ...
+}
+```
+
+Note: we use this ancient version of `org.json` because it is compatible with the one bundled in Android.
diff --git a/src/site/markdown/changelog.md b/src/site/markdown/changelog.md
index d197c228..e671c86a 100644
--- a/src/site/markdown/changelog.md
+++ b/src/site/markdown/changelog.md
@@ -1,3 +1,50 @@
+# History
+
+| Version | Release date |
+|--------------------------------------------------------------------------------------------------------------|---------------|
+| [2.1.2](#211-2025-02-18) | February 2025 |
+| [2.1.1](#211-2024-07-10) | July 2024 |
+| [1.0.2](#102-2022-07-11) (from the [1.x](https://github.com/socketio/socket.io-client-java/tree/1.x) branch) | July 2022 |
+| [2.1.0](#210-2022-07-10) | July 2022 |
+| [2.0.1](#201-2021-04-27) | April 2021 |
+| [2.0.0](#200-2020-12-14) | December 2020 |
+| [1.0.1](#101-2020-12-10) | December 2020 |
+
+
+# Release notes
+
+## [2.1.2](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-2.1.1...socket.io-client-2.1.2) (2025-02-18)
+
+
+### Bug Fixes
+
+* make acks thread safe ([4f45e3c](https://github.com/socketio/socket.io-client-java/commit/4f45e3c1271554da5b3457f447a6d6b060ef5ffd))
+
+
+
+## [2.1.1](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-2.1.0...socket.io-client-2.1.1) (2024-07-10)
+
+
+### Bug Fixes
+
+* discard acknowledgements upon disconnection ([54645ec](https://github.com/socketio/socket.io-client-java/commit/54645ece2cd132f3e305b80904e1fc38bd41c4f9))
+* make sendBuffer thread safe ([#769](https://github.com/socketio/socket.io-client-java/issues/769)) ([b00ae8e](https://github.com/socketio/socket.io-client-java/commit/b00ae8eec1ef0aa5094fca7fad918a437603eb12))
+
+
+
+## [1.0.2](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-1.0.1...socket.io-client-1.0.2) (2022-07-11)
+
+From the "1.x" branch.
+
+### Bug Fixes
+
+* ensure buffered events are sent in order ([8bd35da](https://github.com/socketio/socket.io-client-java/commit/8bd35da19c1314318fe122876d22e30ae3673ff9))
+* ensure randomizationFactor is always between 0 and 1 ([cb966d5](https://github.com/socketio/socket.io-client-java/commit/cb966d5a64790c0584ad97cf55c205cae8bd1287))
+* ensure the payload format is valid ([8664499](https://github.com/socketio/socket.io-client-java/commit/8664499b6f31154f49783531f778dac5387b766b))
+* fix usage with ws:// scheme ([e57160a](https://github.com/socketio/socket.io-client-java/commit/e57160a00ca1fbb38396effdbc87eb10d6759a51))
+* increase the readTimeout value of the default OkHttpClient ([2d87497](https://github.com/socketio/engine.io-client-java/commit/2d874971c2428a7a444b3a33afe66aedcdce3a96)) (from `engine.io-client`)
+
+
## [2.1.0](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-2.0.1...socket.io-client-2.1.0) (2022-07-10)
diff --git a/src/site/markdown/installation.md b/src/site/markdown/installation.md
index a14593a8..de61a1e7 100644
--- a/src/site/markdown/installation.md
+++ b/src/site/markdown/installation.md
@@ -17,7 +17,7 @@ Add the following dependency to your `pom.xml`.
io.socket
socket.io-client
- 2.1.0
+ 2.1.1
```
@@ -26,7 +26,7 @@ Add the following dependency to your `pom.xml`.
Add it as a gradle dependency for Android Studio, in `build.gradle`:
```groovy
-implementation ('io.socket:socket.io-client:2.1.0') {
+implementation ('io.socket:socket.io-client:2.1.1') {
// excluding org.json which is provided by Android
exclude group: 'org.json', module: 'json'
}
@@ -36,8 +36,10 @@ implementation ('io.socket:socket.io-client:2.1.0') {
| `socket.io-client` | `engine.io-client` | `okhttp` |
|-----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
+| `2.1.1` ([diff](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-2.1.0...socket.io-client-2.1.1)) | `2.1.0` | `3.12.12` |
| `2.1.0` ([diff](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-2.0.1...socket.io-client-2.1.0)) | `2.1.0` ([diff](https://github.com/socketio/engine.io-client-java/compare/engine.io-client-2.0.0...engine.io-client-2.1.0)) | `3.12.12` |
| `2.0.1` ([diff](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-2.0.0...socket.io-client-2.0.1)) | `2.0.0` | `3.12.12` |
| `2.0.0` ([diff](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-1.0.1...socket.io-client-2.0.0)) | `2.0.0` ([diff](https://github.com/socketio/engine.io-client-java/compare/engine.io-client-1.0.1...engine.io-client-2.0.0)) | `3.12.12` |
+| `1.0.2` ([diff](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-1.0.1...socket.io-client-1.0.2)) | `1.0.2` ([diff](https://github.com/socketio/engine.io-client-java/compare/engine.io-client-1.0.1...engine.io-client-1.0.2)) | `3.12.12` |
| `1.0.1` ([diff](https://github.com/socketio/socket.io-client-java/compare/socket.io-client-1.0.0...socket.io-client-1.0.1)) | `1.0.1` ([diff](https://github.com/socketio/engine.io-client-java/compare/engine.io-client-1.0.0...engine.io-client-1.0.1)) | `3.12.12` ([changelog](https://square.github.io/okhttp/changelogs/changelog_3x/#version-31212)) |
| `1.0.0` | `1.0.0` | `3.8.1` |
diff --git a/src/test/java/io/socket/parser/ParserTest.java b/src/test/java/io/socket/parser/ParserTest.java
index 17d48863..8b239cb8 100644
--- a/src/test/java/io/socket/parser/ParserTest.java
+++ b/src/test/java/io/socket/parser/ParserTest.java
@@ -1,5 +1,8 @@
package io.socket.parser;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
import org.json.JSONArray;
import org.json.JSONException;
import org.junit.Test;
@@ -49,6 +52,9 @@ public void encodeAck() throws JSONException {
@Test
public void decodeInError() throws JSONException {
+ Logger logger = Logger.getLogger(IOParser.class.getName());
+ Level tmpLevel = logger.getLevel();
+ logger.setLevel(Level.SEVERE);
// Random string
Helpers.testDecodeError("asdf");
// Unknown type
@@ -62,9 +68,10 @@ public void decodeInError() throws JSONException {
// event non numeric id
Helpers.testDecodeError(Parser.EVENT + "2sd");
// event with invalid json data
- Helpers.testDecodeError(Parser.EVENT + "2[\"a\",1,{asdf}]");
Helpers.testDecodeError(Parser.EVENT + "2{}");
Helpers.testDecodeError(Parser.EVENT + "2[]");
Helpers.testDecodeError(Parser.EVENT + "2[null]");
+ Helpers.testDecodeError(Parser.EVENT + "2[\"a\",1,{asdf}]");
+ logger.setLevel(tmpLevel);
}
}