diff --git a/pom.xml b/pom.xml index bacc4d6..0112cc0 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,7 @@ maven-surefire-plugin 2.14.1 + -Dfile.encoding=UTF-8 java.util.logging.config.file diff --git a/src/main/java/com/github/nkzawa/socketio/client/Socket.java b/src/main/java/com/github/nkzawa/socketio/client/Socket.java index 313f724..579938b 100644 --- a/src/main/java/com/github/nkzawa/socketio/client/Socket.java +++ b/src/main/java/com/github/nkzawa/socketio/client/Socket.java @@ -146,6 +146,7 @@ public class Socket extends Emitter { List _args = new ArrayList(args.length + 1); _args.add(event); _args.addAll(Arrays.asList(args)); + JSONArray jsonArgs = new JSONArray(); for (Object arg : _args) { jsonArgs.put(arg); @@ -157,6 +158,7 @@ public class Socket extends Emitter { if (_args.get(_args.size() - 1) instanceof Ack) { logger.fine(String.format("emitting packet with ack id %d", Socket.this.ids)); Socket.this.acks.put(Socket.this.ids, (Ack)_args.remove(_args.size() - 1)); + jsonArgs.remove(jsonArgs.length() - 1); packet.id = Socket.this.ids++; } @@ -240,6 +242,10 @@ public class Socket extends Emitter { this.onack(packet); break; + case Parser.BINARY_ACK: + this.onack(packet); + break; + case Parser.DISCONNECT: this.ondisconnect(); break; @@ -276,7 +282,9 @@ public class Socket extends Emitter { if (sent[0]) return; sent[0] = true; logger.fine(String.format("sending ack %s", args)); - Packet packet = new Packet(Parser.ACK, new JSONArray(args)); + + int type = HasBinaryData.hasBinary(args) ? Parser.BINARY_ACK : Parser.ACK; + Packet packet = new Packet(type, new JSONArray(args)); packet.id = id; self.packet(packet); } diff --git a/src/test/java/com/github/nkzawa/hasbinarydata/HasBinaryDataTest.java b/src/test/java/com/github/nkzawa/hasbinarydata/HasBinaryDataTest.java new file mode 100644 index 0000000..88ab744 --- /dev/null +++ b/src/test/java/com/github/nkzawa/hasbinarydata/HasBinaryDataTest.java @@ -0,0 +1,26 @@ +package com.github.nkzawa.hasbinarydata; + +import org.json.JSONArray; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.nio.charset.Charset; + +import static org.junit.Assert.assertTrue; + +@RunWith(JUnit4.class) +public class HasBinaryDataTest { + + @Test + public void arrayContainsByteArray() { + JSONArray arr = new JSONArray("[1, null, 2]"); + arr.put(1, "asdfasdf".getBytes(Charset.forName("UTF-8"))); + assertTrue(HasBinaryData.hasBinary(arr)); + } + + @Test + public void byteArray() { + assertTrue(HasBinaryData.hasBinary(new byte[0])); + } +} diff --git a/src/test/java/com/github/nkzawa/socketio/client/ConnectionTest.java b/src/test/java/com/github/nkzawa/socketio/client/ConnectionTest.java index c0d3167..fb6f022 100644 --- a/src/test/java/com/github/nkzawa/socketio/client/ConnectionTest.java +++ b/src/test/java/com/github/nkzawa/socketio/client/ConnectionTest.java @@ -9,6 +9,7 @@ import org.junit.runners.JUnit4; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; +import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.CountDownLatch; @@ -76,6 +77,27 @@ public class ConnectionTest extends Connection { latch.await(); } + @Test(timeout = TIMEOUT) + public void receiveDateWithAck() throws URISyntaxException, InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + socket = client(); + socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { + @Override + public void call(Object... objects) { + socket.emit("getAckDate", new JSONObject("{test: true}"), new Ack() { + @Override + public void call(Object... args) { + assertThat(args[0], instanceOf(String.class)); + socket.close(); + latch.countDown(); + } + }); + } + }); + socket.connect(); + latch.await(); + } + @Test(timeout = TIMEOUT) public void workWithFalse() throws URISyntaxException, InterruptedException { final CountDownLatch latch = new CountDownLatch(1); @@ -98,6 +120,42 @@ public class ConnectionTest extends Connection { latch.await(); } + @Test(timeout = TIMEOUT) + public void receiveUTF8MultibyteCharacters() throws URISyntaxException, InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + final String[] correct = new String[] { + "てすと", + "Я Б Г Д Ж Й", + "Ä ä Ü ü ß", + "utf8 — string", + "utf8 — string" + }; + + socket = client(); + final int[] i = new int[] {0}; + socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { + @Override + public void call(Object... objects) { + socket.on("echoBack", new Emitter.Listener() { + @Override + public void call(Object... args) { + assertThat((String)args[0], is(correct[i[0]])); + i[0]++; + if (i[0] == correct.length) { + socket.close(); + latch.countDown(); + } + } + }); + for (String data : correct) { + socket.emit("echo", data); + } + } + }); + socket.connect(); + latch.await(); + } + @Test(timeout = TIMEOUT) public void connectToNamespaceAfterConnectionEstablished() throws URISyntaxException, InterruptedException { final CountDownLatch latch = new CountDownLatch(1); @@ -209,7 +267,7 @@ public class ConnectionTest extends Connection { } @Test(timeout = TIMEOUT) - public void notTryToReconnectWithIncorrectPort() throws URISyntaxException, InterruptedException { + public void notTryToReconnectWithIncorrectPortWhenReconnectionDisabled() throws URISyntaxException, InterruptedException { final CountDownLatch latch = new CountDownLatch(1); IO.Options opts = new IO.Options(); opts.reconnection = false; @@ -241,6 +299,53 @@ public class ConnectionTest extends Connection { latch.await(); } + @Test(timeout = TIMEOUT) + public void emitDateAsString() throws URISyntaxException, InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + socket = client(); + socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { + @Override + public void call(Object... objects) { + socket.emit("echo", new Date()); + socket.on("echoBack", new Emitter.Listener() { + @Override + public void call(Object... args) { + assertThat(args[0], instanceOf(String.class)); + socket.close(); + latch.countDown(); + } + }); + } + }); + socket.connect(); + latch.await(); + } + + @Test(timeout = TIMEOUT) + public void emitDateInObject() throws URISyntaxException, InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + socket = client(); + socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { + @Override + public void call(Object... objects) { + JSONObject data = new JSONObject(); + data.put("date", new Date()); + socket.emit("echo", data); + socket.on("echoBack", new Emitter.Listener() { + @Override + public void call(Object... args) { + assertThat(args[0], instanceOf(JSONObject.class)); + assertThat(((JSONObject)args[0]).get("date"), instanceOf(String.class)); + socket.close(); + latch.countDown(); + } + }); + } + }); + socket.connect(); + latch.await(); + } + @Test(timeout = TIMEOUT) public void sendAndGetBinaryData() throws URISyntaxException, InterruptedException { final CountDownLatch latch = new CountDownLatch(1); diff --git a/src/test/resources/index.js b/src/test/resources/index.js index c7d2f92..a4e21ba 100644 --- a/src/test/resources/index.js +++ b/src/test/resources/index.js @@ -29,6 +29,10 @@ io.of(nsp).on('connection', function(socket) { }); }); + socket.on('getAckDate', function(data, callback) { + callback(new Date()); + }); + socket.on('disconnect', function() { console.log('disconnect'); });