packet;
while ((packet = this.sendBuffer.poll()) != null) {
+ Ack ack = acks.get(packet.id);
+ if (ack instanceof AckWithTimeOut)
+ ((AckWithTimeOut) ack).resetTimer();
this.packet(packet);
}
this.sendBuffer.clear();
@@ -422,7 +404,12 @@ private void destroy() {
this.subs = null;
}
- this.io.destroy(this);
+ for (Ack ack : acks.values()) {
+ if (ack instanceof AckWithTimeOut)
+ ((AckWithTimeOut) ack).cancelTimer();
+ }
+
+ this.io.destroy();
}
/**
@@ -470,7 +457,7 @@ public boolean connected() {
/**
* A property on the socket instance that is equal to the underlying engine.io socket id.
- *
+ *
* The value is present once the socket has connected, is removed when the socket disconnects and is updated if the socket reconnects.
*
* @return a socket id
diff --git a/src/main/java/io/socket/client/SocketIOException.java b/src/main/java/com/kaleyra/socket_io/client/SocketIOException.java
similarity index 90%
rename from src/main/java/io/socket/client/SocketIOException.java
rename to src/main/java/com/kaleyra/socket_io/client/SocketIOException.java
index 5ad67dca..87065f39 100644
--- a/src/main/java/io/socket/client/SocketIOException.java
+++ b/src/main/java/com/kaleyra/socket_io/client/SocketIOException.java
@@ -1,4 +1,4 @@
-package io.socket.client;
+package com.kaleyra.socket_io.client;
public class SocketIOException extends Exception {
diff --git a/src/main/java/com/kaleyra/socket_io/client/SocketOptionBuilder.java b/src/main/java/com/kaleyra/socket_io/client/SocketOptionBuilder.java
new file mode 100644
index 00000000..f7872557
--- /dev/null
+++ b/src/main/java/com/kaleyra/socket_io/client/SocketOptionBuilder.java
@@ -0,0 +1,202 @@
+package com.kaleyra.socket_io.client;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Convenient builder class that helps creating
+ * {@link IO.Options Client Option} object as builder pattern.
+ * Finally, you can get option object with call {@link #build()} method.
+ *
+ * @author junbong
+ */
+public class SocketOptionBuilder {
+ /**
+ * Construct new builder with default preferences.
+ *
+ * @return new builder object
+ * @see SocketOptionBuilder#builder(IO.Options)
+ */
+ public static SocketOptionBuilder builder() {
+ return new SocketOptionBuilder();
+ }
+
+
+ /**
+ * Construct this builder from specified option object.
+ * The option that returned from {@link #build()} method
+ * is not equals with given option.
+ * In other words, builder creates new option object
+ * and copy all preferences from given option.
+ *
+ * @param options option object which to copy preferences
+ * @return new builder object
+ */
+ public static SocketOptionBuilder builder(IO.Options options) {
+ return new SocketOptionBuilder(options);
+ }
+
+
+ private final IO.Options options = new IO.Options();
+
+
+ /**
+ * Construct new builder with default preferences.
+ */
+ protected SocketOptionBuilder() {
+ this(null);
+ }
+
+
+ /**
+ * Construct this builder from specified option object.
+ * The option that returned from {@link #build()} method
+ * is not equals with given option.
+ * In other words, builder creates new option object
+ * and copy all preferences from given option.
+ *
+ * @param options option object which to copy preferences. Null-ok.
+ */
+ protected SocketOptionBuilder(IO.Options options) {
+ if (options != null) {
+ this.setForceNew(options.forceNew)
+ .setMultiplex(options.multiplex)
+ .setReconnection(options.reconnection)
+ .setReconnectionAttempts(options.reconnectionAttempts)
+ .setReconnectionDelay(options.reconnectionDelay)
+ .setReconnectionDelayMax(options.reconnectionDelayMax)
+ .setRandomizationFactor(options.randomizationFactor)
+ .setTimeout(options.timeout)
+ .setTransports(options.transports)
+ .setUpgrade(options.upgrade)
+ .setRememberUpgrade(options.rememberUpgrade)
+ .setHost(options.host)
+ .setHostname(options.hostname)
+ .setPort(options.port)
+ .setPolicyPort(options.policyPort)
+ .setSecure(options.secure)
+ .setPath(options.path)
+ .setQuery(options.query)
+ .setAuth(options.auth)
+ .setExtraHeaders(options.extraHeaders)
+ .setEnablePollingCookies(options.enablePollingCookies);
+ }
+ }
+
+ public SocketOptionBuilder setForceNew(boolean forceNew) {
+ this.options.forceNew = forceNew;
+ return this;
+ }
+
+ public SocketOptionBuilder setMultiplex(boolean multiplex) {
+ this.options.multiplex = multiplex;
+ return this;
+ }
+
+ public SocketOptionBuilder setReconnection(boolean reconnection) {
+ this.options.reconnection = reconnection;
+ return this;
+ }
+
+ public SocketOptionBuilder setReconnectionAttempts(int reconnectionAttempts) {
+ this.options.reconnectionAttempts = reconnectionAttempts;
+ return this;
+ }
+
+ public SocketOptionBuilder setReconnectionDelay(long reconnectionDelay) {
+ this.options.reconnectionDelay = reconnectionDelay;
+ return this;
+ }
+
+ public SocketOptionBuilder setReconnectionDelayMax(long reconnectionDelayMax) {
+ this.options.reconnectionDelayMax = reconnectionDelayMax;
+ return this;
+ }
+
+
+ public SocketOptionBuilder setRandomizationFactor(double randomizationFactor) {
+ this.options.randomizationFactor = randomizationFactor;
+ return this;
+ }
+
+ public SocketOptionBuilder setTimeout(long timeout) {
+ this.options.timeout = timeout;
+ return this;
+ }
+
+ public SocketOptionBuilder setTransports(String[] transports) {
+ this.options.transports = transports;
+ return this;
+ }
+
+ public SocketOptionBuilder setUpgrade(boolean upgrade) {
+ this.options.upgrade = upgrade;
+ return this;
+ }
+
+ public SocketOptionBuilder setRememberUpgrade(boolean rememberUpgrade) {
+ this.options.rememberUpgrade = rememberUpgrade;
+ return this;
+ }
+
+ public SocketOptionBuilder setHost(String host) {
+ this.options.host = host;
+ return this;
+ }
+
+ public SocketOptionBuilder setHostname(String hostname) {
+ this.options.hostname = hostname;
+ return this;
+ }
+
+ public SocketOptionBuilder setPort(int port) {
+ this.options.port = port;
+ return this;
+ }
+
+ public SocketOptionBuilder setPolicyPort(int policyPort) {
+ this.options.policyPort = policyPort;
+ return this;
+ }
+
+ public SocketOptionBuilder setQuery(String query) {
+ this.options.query = query;
+ return this;
+ }
+
+ public SocketOptionBuilder setSecure(boolean secure) {
+ this.options.secure = secure;
+ return this;
+ }
+
+ public SocketOptionBuilder setPath(String path) {
+ this.options.path = path;
+ return this;
+ }
+
+ public SocketOptionBuilder setAuth(Map auth) {
+ this.options.auth = auth;
+ return this;
+ }
+
+ public SocketOptionBuilder setExtraHeaders(Map> extraHeaders) {
+ this.options.extraHeaders = extraHeaders;
+ return this;
+ }
+
+ public SocketOptionBuilder setEnablePollingCookies(boolean enablePollingCookies) {
+ this.options.enablePollingCookies = enablePollingCookies;
+ return this;
+ }
+
+ /**
+ * Finally retrieve {@link IO.Options} object
+ * from this builder.
+ *
+ * @return option that built from this builder
+ */
+ public IO.Options build() {
+ return this.options;
+ }
+}
diff --git a/src/main/java/com/kaleyra/socket_io/client/Url.java b/src/main/java/com/kaleyra/socket_io/client/Url.java
new file mode 100644
index 00000000..c75c40bb
--- /dev/null
+++ b/src/main/java/com/kaleyra/socket_io/client/Url.java
@@ -0,0 +1,84 @@
+package com.kaleyra.socket_io.client;
+
+import java.net.URI;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Url {
+
+ /**
+ * Expected format: "[id:password@]host[:port]"
+ */
+ private static Pattern PATTERN_AUTHORITY = Pattern.compile("^(.*@)?([^:]+)(:\\d+)?$");
+
+ private Url() {}
+
+ static class ParsedURI {
+ public final URI uri;
+ public final String id;
+
+ public ParsedURI(URI uri, String id) {
+ this.uri = uri;
+ this.id = id;
+ }
+ }
+
+ public static ParsedURI parse(URI uri) {
+ String protocol = uri.getScheme();
+ if (protocol == null || !protocol.matches("^https?|wss?$")) {
+ protocol = "https";
+ }
+
+ int port = uri.getPort();
+ if (port == -1) {
+ if ("http".equals(protocol) || "ws".equals(protocol)) {
+ port = 80;
+ } else if ("https".equals(protocol) || "wss".equals(protocol)) {
+ port = 443;
+ }
+ }
+
+ String path = uri.getRawPath();
+ if (path == null || path.length() == 0) {
+ path = "/";
+ }
+
+ String userInfo = uri.getRawUserInfo();
+ String query = uri.getRawQuery();
+ String fragment = uri.getRawFragment();
+ String _host = uri.getHost();
+ if (_host == null) {
+ // might happen on some of Samsung Devices such as S4.
+ _host = extractHostFromAuthorityPart(uri.getRawAuthority());
+ }
+ URI completeUri = URI.create(protocol + "://"
+ + (userInfo != null ? userInfo + "@" : "")
+ + _host
+ + (port != -1 ? ":" + port : "")
+ + path
+ + (query != null ? "?" + query : "")
+ + (fragment != null ? "#" + fragment : ""));
+ String id = protocol + "://" + _host + ":" + port;
+
+ return new ParsedURI(completeUri, id);
+ }
+
+
+ private static String extractHostFromAuthorityPart(String authority)
+ {
+ if (authority == null) {
+ throw new RuntimeException("unable to parse the host from the authority");
+ }
+
+ Matcher matcher = PATTERN_AUTHORITY.matcher(authority);
+
+ // If the authority part does not match the expected format.
+ if (!matcher.matches()) {
+ throw new RuntimeException("unable to parse the host from the authority");
+ }
+
+ // Return the host part.
+ return matcher.group(2);
+ }
+
+}
diff --git a/src/main/java/io/socket/hasbinary/HasBinary.java b/src/main/java/com/kaleyra/socket_io/hasbinary/HasBinary.java
similarity index 97%
rename from src/main/java/io/socket/hasbinary/HasBinary.java
rename to src/main/java/com/kaleyra/socket_io/hasbinary/HasBinary.java
index 630be88a..7b9a2cbd 100644
--- a/src/main/java/io/socket/hasbinary/HasBinary.java
+++ b/src/main/java/com/kaleyra/socket_io/hasbinary/HasBinary.java
@@ -1,4 +1,4 @@
-package io.socket.hasbinary;
+package com.kaleyra.socket_io.hasbinary;
import org.json.JSONArray;
import org.json.JSONException;
diff --git a/src/main/java/io/socket/parser/Binary.java b/src/main/java/com/kaleyra/socket_io/parser/Binary.java
similarity index 98%
rename from src/main/java/io/socket/parser/Binary.java
rename to src/main/java/com/kaleyra/socket_io/parser/Binary.java
index b390da62..7c0d244f 100644
--- a/src/main/java/io/socket/parser/Binary.java
+++ b/src/main/java/com/kaleyra/socket_io/parser/Binary.java
@@ -1,4 +1,4 @@
-package io.socket.parser;
+package com.kaleyra.socket_io.parser;
import org.json.JSONArray;
import org.json.JSONException;
@@ -20,7 +20,7 @@ public class Binary {
@SuppressWarnings("unchecked")
public static DeconstructedPacket deconstructPacket(Packet packet) {
- List buffers = new ArrayList();
+ List buffers = new ArrayList<>();
packet.data = _deconstructPacket(packet.data, buffers);
packet.attachments = buffers.size();
diff --git a/src/main/java/com/kaleyra/socket_io/parser/DecodingException.java b/src/main/java/com/kaleyra/socket_io/parser/DecodingException.java
new file mode 100644
index 00000000..10985da3
--- /dev/null
+++ b/src/main/java/com/kaleyra/socket_io/parser/DecodingException.java
@@ -0,0 +1,7 @@
+package com.kaleyra.socket_io.parser;
+
+public class DecodingException extends RuntimeException {
+ public DecodingException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/io/socket/parser/IOParser.java b/src/main/java/com/kaleyra/socket_io/parser/IOParser.java
similarity index 81%
rename from src/main/java/io/socket/parser/IOParser.java
rename to src/main/java/com/kaleyra/socket_io/parser/IOParser.java
index 813c16ca..659d48e0 100644
--- a/src/main/java/io/socket/parser/IOParser.java
+++ b/src/main/java/com/kaleyra/socket_io/parser/IOParser.java
@@ -1,7 +1,9 @@
-package io.socket.parser;
+package com.kaleyra.socket_io.parser;
-import io.socket.hasbinary.HasBinary;
+import com.kaleyra.socket_io.hasbinary.HasBinary;
+import org.json.JSONArray;
import org.json.JSONException;
+import org.json.JSONObject;
import org.json.JSONTokener;
import java.util.ArrayList;
@@ -14,10 +16,6 @@ final public class IOParser implements Parser {
private static final Logger logger = Logger.getLogger(IOParser.class.getName());
- private static Packet error() {
- return new Packet(ERROR, "parser error");
- }
-
private IOParser() {}
final public static class Encoder implements Parser.Encoder {
@@ -126,12 +124,16 @@ private static Packet decodeString(String str) {
int i = 0;
int length = str.length();
- Packet