support binary
This commit is contained in:
@@ -348,9 +348,13 @@ public class Manager extends Emitter {
|
||||
self.encoding = true;
|
||||
this.encoder.encode(packet, new Parser.Encoder.Callback() {
|
||||
@Override
|
||||
public void call(String[] encodedPackets) {
|
||||
for (int i = 0; i < encodedPackets.length; i++) {
|
||||
self.engine.write(encodedPackets[i]);
|
||||
public void call(Object[] encodedPackets) {
|
||||
for (Object packet : encodedPackets) {
|
||||
if (packet instanceof String) {
|
||||
self.engine.write((String)packet);
|
||||
} else if (packet instanceof byte[]) {
|
||||
self.engine.write((byte[])packet);
|
||||
}
|
||||
}
|
||||
self.encoding = false;
|
||||
self.processPacketQueue();
|
||||
|
||||
@@ -134,26 +134,26 @@ public class Socket extends Emitter {
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
@Override
|
||||
public Emitter emit(final String event, final Object... arguments) {
|
||||
public Emitter emit(final String event, final Object... args) {
|
||||
EventThread.exec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (events.containsKey(event)) {
|
||||
Socket.super.emit(event, arguments);
|
||||
Socket.super.emit(event, args);
|
||||
return;
|
||||
}
|
||||
|
||||
List<Object> args = new ArrayList<Object>(arguments.length + 1);
|
||||
args.add(event);
|
||||
args.addAll(Arrays.asList(arguments));
|
||||
JSONArray _args = new JSONArray(args);
|
||||
List<Object> _args = new ArrayList<Object>(args.length + 1);
|
||||
_args.add(event);
|
||||
_args.addAll(Arrays.asList(args));
|
||||
JSONArray jsonArgs = new JSONArray(_args);
|
||||
int parserType = Parser.EVENT;
|
||||
if (HasBinaryData.hasBinary(_args)) { parserType = Parser.BINARY_EVENT; }
|
||||
Packet packet = new Packet(parserType, _args);
|
||||
if (HasBinaryData.hasBinary(jsonArgs)) { parserType = Parser.BINARY_EVENT; }
|
||||
Packet packet = new Packet(parserType, jsonArgs);
|
||||
|
||||
if (args.get(args.size() - 1) instanceof Ack) {
|
||||
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));
|
||||
Socket.this.acks.put(Socket.this.ids, (Ack)_args.remove(_args.size() - 1));
|
||||
packet.id = Socket.this.ids++;
|
||||
}
|
||||
|
||||
|
||||
96
src/main/java/com/github/nkzawa/socketio/parser/Binary.java
Normal file
96
src/main/java/com/github/nkzawa/socketio/parser/Binary.java
Normal file
@@ -0,0 +1,96 @@
|
||||
package com.github.nkzawa.socketio.parser;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class Binary {
|
||||
|
||||
private static final String KEY_PLACEHOLDER = "_placeholder";
|
||||
|
||||
private static final String KEY_NUM = "num";
|
||||
|
||||
|
||||
public static DeconstructedPacket deconstructPacket(Packet packet) {
|
||||
List<byte[]> buffers = new ArrayList<byte[]>();
|
||||
|
||||
packet.data = deconstructBinPackRecursive(packet.data, buffers);
|
||||
packet.attachments = buffers.size();
|
||||
|
||||
DeconstructedPacket result = new DeconstructedPacket();
|
||||
result.packet = packet;
|
||||
result.buffers = buffers.toArray(new byte[buffers.size()][]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Object deconstructBinPackRecursive(Object data, List<byte[]> buffers) {
|
||||
if (data == null) return null;
|
||||
|
||||
if (data instanceof byte[]) {
|
||||
JSONObject placeholder = new JSONObject();
|
||||
placeholder.put(KEY_PLACEHOLDER, true);
|
||||
placeholder.put(KEY_NUM, buffers.size());
|
||||
buffers.add((byte[])data);
|
||||
return placeholder;
|
||||
} else if (data instanceof JSONArray) {
|
||||
JSONArray newData = new JSONArray();
|
||||
JSONArray _data = (JSONArray)data;
|
||||
int len = _data.length();
|
||||
for (int i = 0; i < len; i ++) {
|
||||
newData.put(i, deconstructBinPackRecursive(_data.get(i), buffers));
|
||||
}
|
||||
return newData;
|
||||
} else if (data instanceof JSONObject) {
|
||||
JSONObject newData = new JSONObject();
|
||||
JSONObject _data = (JSONObject)data;
|
||||
Iterator<?> iterator = _data.keys();
|
||||
while (iterator.hasNext()) {
|
||||
String key = (String)iterator.next();
|
||||
newData.put(key, deconstructBinPackRecursive(_data.get(key), buffers));
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static Packet reconstructPacket(Packet packet, byte[][] buffers) {
|
||||
packet.data = reconstructBinPackRecursive(packet.data, buffers);
|
||||
packet.attachments = -1;
|
||||
return packet;
|
||||
}
|
||||
|
||||
private static Object reconstructBinPackRecursive(Object data, byte[][] buffers) {
|
||||
if (data instanceof JSONArray) {
|
||||
JSONArray _data = (JSONArray)data;
|
||||
int len = _data.length();
|
||||
for (int i = 0; i < len; i ++) {
|
||||
_data.put(i, reconstructBinPackRecursive(_data.get(i), buffers));
|
||||
}
|
||||
return _data;
|
||||
} else if (data instanceof JSONObject) {
|
||||
JSONObject _data = (JSONObject)data;
|
||||
if (_data.optBoolean(KEY_PLACEHOLDER)) {
|
||||
int num = _data.optInt(KEY_NUM, -1);
|
||||
return num >= 0 && num < buffers.length ? buffers[num] : null;
|
||||
}
|
||||
Iterator<?> iterator = _data.keys();
|
||||
while (iterator.hasNext()) {
|
||||
String key = (String)iterator.next();
|
||||
_data.put(key, reconstructBinPackRecursive(_data.get(key), buffers));
|
||||
}
|
||||
return _data;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static class DeconstructedPacket {
|
||||
|
||||
public Packet packet;
|
||||
public byte[][] buffers;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.json.JSONException;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -113,12 +114,17 @@ public class Parser {
|
||||
}
|
||||
|
||||
private void encodeAsBinary(Packet obj, Callback callback) {
|
||||
// TODO
|
||||
Binary.DeconstructedPacket deconstruction = Binary.deconstructPacket(obj);
|
||||
String pack = encodeAsString(deconstruction.packet);
|
||||
List<Object> buffers = new ArrayList<Object>(Arrays.asList(deconstruction.buffers));
|
||||
|
||||
buffers.add(0, pack);
|
||||
callback.call(buffers.toArray());
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
|
||||
public void call(String[] data);
|
||||
public void call(Object[] data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +248,10 @@ public class Parser {
|
||||
public Packet takeBinaryData(byte[] binData) {
|
||||
this.buffers.add(binData);
|
||||
if (this.buffers.size() == this.reconPack.attachments) {
|
||||
// TODO:
|
||||
Packet packet = Binary.reconstructPacket(this.reconPack,
|
||||
this.buffers.toArray(new byte[this.buffers.size()][]));
|
||||
this.finishReconstruction();
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@@ -16,21 +18,21 @@ public class ParserTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void connect() {
|
||||
public void encodeConnection() {
|
||||
Packet packet = new Packet(Parser.CONNECT);
|
||||
packet.nsp = "/woot";
|
||||
test(packet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disconnect() {
|
||||
public void encodeDisconnect() {
|
||||
Packet packet = new Packet(Parser.DISCONNECT);
|
||||
packet.nsp = "/woot";
|
||||
test(packet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void event() {
|
||||
public void encodeEvent() {
|
||||
Packet packet1 = new Packet(Parser.EVENT);
|
||||
packet1.data = new JSONTokener("[\"a\", 1, {}]").nextValue();
|
||||
packet1.nsp = "/";
|
||||
@@ -43,7 +45,7 @@ public class ParserTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ack() {
|
||||
public void encodeAck() {
|
||||
Packet packet = new Packet(Parser.ACK);
|
||||
packet.data = new JSONTokener("[\"a\", 1, {}]").nextValue();
|
||||
packet.id = 123;
|
||||
@@ -51,10 +53,19 @@ public class ParserTest {
|
||||
test(packet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeBytes() {
|
||||
Packet packet = new Packet(Parser.BINARY_EVENT);
|
||||
packet.data = "abc".getBytes(Charset.forName("UTF-8"));
|
||||
packet.id = 23;
|
||||
packet.nsp = "/cool";
|
||||
testBin(packet);
|
||||
}
|
||||
|
||||
private void test(final Packet obj) {
|
||||
encoder.encode(obj, new Parser.Encoder.Callback() {
|
||||
@Override
|
||||
public void call(String[] encodedPackets) {
|
||||
public void call(Object[] encodedPackets) {
|
||||
Parser.Decoder decoder = new Parser.Decoder();
|
||||
decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() {
|
||||
@Override
|
||||
@@ -71,7 +82,39 @@ public class ParserTest {
|
||||
assertThat(packet.attachments, is(obj.attachments));
|
||||
}
|
||||
});
|
||||
decoder.add(encodedPackets[0]);
|
||||
decoder.add((String)encodedPackets[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void testBin(final Packet obj) {
|
||||
final Object originalData = obj.data;
|
||||
encoder.encode(obj, new Parser.Encoder.Callback() {
|
||||
@Override
|
||||
public void call(Object[] encodedPackets) {
|
||||
Parser.Decoder decoder = new Parser.Decoder();
|
||||
decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() {
|
||||
@Override
|
||||
public void call(Object... args) {
|
||||
Packet packet = (Packet)args[0];
|
||||
obj.data = originalData;
|
||||
obj.attachments = -1;
|
||||
|
||||
assertThat(packet.type, is(obj.type));
|
||||
assertThat(packet.id, is(obj.id));
|
||||
assertThat(packet.data, is(obj.data));
|
||||
assertThat(packet.nsp, is(obj.nsp));
|
||||
assertThat(packet.attachments, is(obj.attachments));
|
||||
}
|
||||
});
|
||||
|
||||
for (Object packet : encodedPackets) {
|
||||
if (packet instanceof String) {
|
||||
decoder.add((String)packet);
|
||||
} else if (packet instanceof byte[]) {
|
||||
decoder.add((byte[])packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user