fix: json socket send data length
This commit is contained in:
@@ -6,10 +6,13 @@ import android.util.Log;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
@@ -17,7 +20,7 @@ import io.reactivex.subjects.PublishSubject;
|
|||||||
|
|
||||||
public class JsonSocket {
|
public class JsonSocket {
|
||||||
|
|
||||||
private static final byte DELIMITER = '#';
|
private static final char DELIMITER = '#';
|
||||||
private static final String DELIMITER_STRING = "#";
|
private static final String DELIMITER_STRING = "#";
|
||||||
private static final String LOG_TAG = "JsonSocket";
|
private static final String LOG_TAG = "JsonSocket";
|
||||||
|
|
||||||
@@ -38,8 +41,9 @@ public class JsonSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int write(JsonElement element) throws IOException {
|
public int write(JsonElement element) throws IOException {
|
||||||
byte[] bytes = element.toString().getBytes();
|
String json = element.toString();
|
||||||
String length = bytes.length + DELIMITER_STRING;
|
byte[] bytes = json.getBytes();
|
||||||
|
String length = json.length() + DELIMITER_STRING;
|
||||||
mOutputStream.write(length.getBytes());
|
mOutputStream.write(length.getBytes());
|
||||||
mOutputStream.write(bytes);
|
mOutputStream.write(bytes);
|
||||||
Log.d(LOG_TAG, "write: length = " + bytes.length + ", json = " + element);
|
Log.d(LOG_TAG, "write: length = " + bytes.length + ", json = " + element);
|
||||||
@@ -70,7 +74,9 @@ public class JsonSocket {
|
|||||||
|
|
||||||
private void dispatchJson(String json) {
|
private void dispatchJson(String json) {
|
||||||
try {
|
try {
|
||||||
JsonElement element = mJsonParser.parse(json);
|
JsonReader reader = new JsonReader(new StringReader(json));
|
||||||
|
reader.setLenient(true);
|
||||||
|
JsonElement element = mJsonParser.parse(reader);
|
||||||
mJsonElementPublishSubject.onNext(element);
|
mJsonElementPublishSubject.onNext(element);
|
||||||
} catch (JsonParseException e) {
|
} catch (JsonParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -82,25 +88,25 @@ public class JsonSocket {
|
|||||||
return mClosed;
|
return mClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ByteQueue {
|
private static class CharQueue {
|
||||||
byte[] data;
|
char[] data;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
public ByteQueue(int initialCapacity) {
|
public CharQueue(int initialCapacity) {
|
||||||
data = new byte[initialCapacity];
|
data = new char[initialCapacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
int read(InputStream stream) throws IOException {
|
int read(InputStreamReader reader) throws IOException {
|
||||||
if (size >= data.length) {
|
if (size >= data.length) {
|
||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
int end = offset + size;
|
int end = offset + size;
|
||||||
int n;
|
int n;
|
||||||
if (end >= data.length) {
|
if (end >= data.length) {
|
||||||
n = stream.read(data, 0, offset);
|
n = reader.read(data, 0, offset);
|
||||||
} else {
|
} else {
|
||||||
n = stream.read(data, end, data.length - end);
|
n = reader.read(data, end, data.length - end);
|
||||||
}
|
}
|
||||||
size += n;
|
size += n;
|
||||||
return n;
|
return n;
|
||||||
@@ -127,7 +133,7 @@ public class JsonSocket {
|
|||||||
if (end < data.length) {
|
if (end < data.length) {
|
||||||
str = new String(data, offset, len);
|
str = new String(data, offset, len);
|
||||||
} else {
|
} else {
|
||||||
byte[] bytes = new byte[len];
|
char[] bytes = new char[len];
|
||||||
int firstPartLength = data.length - offset;
|
int firstPartLength = data.length - offset;
|
||||||
int secondPartLength = len - firstPartLength;
|
int secondPartLength = len - firstPartLength;
|
||||||
System.arraycopy(data, offset, bytes, 0, firstPartLength);
|
System.arraycopy(data, offset, bytes, 0, firstPartLength);
|
||||||
@@ -139,7 +145,7 @@ public class JsonSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resize() {
|
private void resize() {
|
||||||
byte[] newData = new byte[data.length * 2];
|
char[] newData = new char[data.length * 2];
|
||||||
int end = offset + size;
|
int end = offset + size;
|
||||||
if (end < data.length) {
|
if (end < data.length) {
|
||||||
System.arraycopy(data, offset, newData, 0, size);
|
System.arraycopy(data, offset, newData, 0, size);
|
||||||
@@ -159,13 +165,13 @@ public class JsonSocket {
|
|||||||
private class SocketReader implements Runnable {
|
private class SocketReader implements Runnable {
|
||||||
|
|
||||||
private final Socket mSocket;
|
private final Socket mSocket;
|
||||||
private final InputStream mInputStream;
|
private final InputStreamReader mInputStreamReader;
|
||||||
private int mJsonDataLength = -1;
|
private int mJsonDataLength = -1;
|
||||||
private ByteQueue mByteQueue = new ByteQueue(4096);
|
private CharQueue mCharQueue = new CharQueue(4096);
|
||||||
|
|
||||||
private SocketReader(Socket socket) throws IOException {
|
private SocketReader(Socket socket) throws IOException {
|
||||||
mSocket = socket;
|
mSocket = socket;
|
||||||
mInputStream = mSocket.getInputStream();
|
mInputStreamReader = new InputStreamReader(mSocket.getInputStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,22 +189,22 @@ public class JsonSocket {
|
|||||||
|
|
||||||
private void readLoop() throws Exception {
|
private void readLoop() throws Exception {
|
||||||
int n;
|
int n;
|
||||||
while ((n = mByteQueue.read(mInputStream)) > 0) {
|
while ((n = mCharQueue.read(mInputStreamReader)) > 0) {
|
||||||
onChunk(mByteQueue, n);
|
onChunk(mCharQueue, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onChunk(ByteQueue byteQueue, int chunkSize) {
|
private void onChunk(CharQueue charQueue, int chunkSize) {
|
||||||
if (mJsonDataLength <= 0) {
|
if (mJsonDataLength <= 0) {
|
||||||
tryReadingJsonDataLength(byteQueue, chunkSize);
|
tryReadingJsonDataLength(charQueue, chunkSize);
|
||||||
}
|
}
|
||||||
if (mJsonDataLength <= 0) {
|
if (mJsonDataLength <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (byteQueue.size < mJsonDataLength) {
|
if (charQueue.size < mJsonDataLength) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String json = byteQueue.popAsString(mJsonDataLength);
|
String json = charQueue.popAsString(mJsonDataLength);
|
||||||
Log.d(LOG_TAG, "json = " + json);
|
Log.d(LOG_TAG, "json = " + json);
|
||||||
mJsonDataLength = -1;
|
mJsonDataLength = -1;
|
||||||
dispatchJson(json);
|
dispatchJson(json);
|
||||||
@@ -206,14 +212,14 @@ public class JsonSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void tryReadingJsonDataLength(ByteQueue byteQueue, int chunkSize) {
|
private void tryReadingJsonDataLength(CharQueue charQueue, int chunkSize) {
|
||||||
int end = byteQueue.offset + byteQueue.size;
|
int end = charQueue.offset + charQueue.size;
|
||||||
int start = end - chunkSize;
|
int start = end - chunkSize;
|
||||||
for (int i = start; i < end; i++) {
|
for (int i = start; i < end; i++) {
|
||||||
if (byteQueue.data[i] == DELIMITER) {
|
if (charQueue.data[i] == DELIMITER) {
|
||||||
String jsonDataLength = new String(byteQueue.data, byteQueue.offset, i - byteQueue.offset);
|
String jsonDataLength = new String(charQueue.data, charQueue.offset, i - charQueue.offset);
|
||||||
Log.d(LOG_TAG, "json data length = " + jsonDataLength);
|
Log.d(LOG_TAG, "json data length = " + jsonDataLength);
|
||||||
byteQueue.pop(i - byteQueue.offset + 1);
|
charQueue.pop(i - charQueue.offset + 1);
|
||||||
receiveJsonDataLength(jsonDataLength);
|
receiveJsonDataLength(jsonDataLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user