Skip to content

Commit 706d2d0

Browse files
Fixed ping/pong
Change-Id: I29bbe333a773162a06e74f2c6b0aaeff26de685f
1 parent dcd8d91 commit 706d2d0

3 files changed

Lines changed: 135 additions & 13 deletions

File tree

AndroidSocketIO/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ dependencies {
2929
androidTestCompile fileTree(dir: 'src/androidTest/libs', include: '*.jar')
3030
}
3131

32-
def baseVersionName = "1.1.3"
32+
def baseVersionName = "1.1.4"
3333
if (project.hasProperty("versionSuffix")) {
3434
project.ext.versionSuffix = project.versionSuffix
3535
} else {

AndroidSocketIO/src/androidTest/java/com/appunite/websocket/WebsocketTest.java

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
import com.appunite.socketio.NotConnectedException;
77

88
import org.hamcrest.Matchers;
9-
import org.json.JSONObject;
109
import org.mockito.ArgumentCaptor;
1110

1211
import java.io.IOException;
12+
import java.util.Arrays;
1313
import java.util.concurrent.atomic.AtomicBoolean;
1414
import java.util.concurrent.atomic.AtomicReference;
1515

1616
import static org.hamcrest.MatcherAssert.assertThat;
1717
import static org.hamcrest.Matchers.*;
18+
import static org.mockito.Matchers.any;
1819
import static org.mockito.Matchers.argThat;
1920
import static org.mockito.Mockito.mock;
2021
import static org.mockito.Mockito.reset;
@@ -29,7 +30,7 @@ public class WebsocketTest extends AndroidTestCase {
2930
@Override
3031
public void setUp() throws Exception {
3132
super.setUp();
32-
mUri = Uri.parse("wss://some.test.website.com/");
33+
mUri = Uri.parse("wss://www.yourserver.com/");
3334
mListener = mock(WebSocketListener.class);
3435
}
3536

@@ -49,7 +50,7 @@ public void run() {
4950
reference.set(e);
5051
} catch (WrongWebsocketResponse e) {
5152
reference.set(e);
52-
} catch (InterruptedException e) {
53+
} catch (InterruptedException ignore) {
5354
}
5455
}
5556
}).start();
@@ -67,7 +68,7 @@ public void testConnection() throws Exception {
6768
final WebSocket webSocket = new WebSocket(mListener);
6869

6970
final AtomicBoolean interrupted = new AtomicBoolean(false);
70-
new Thread(new Runnable() {
71+
final Thread thread = new Thread(new Runnable() {
7172
@Override
7273
public void run() {
7374
try {
@@ -78,14 +79,106 @@ public void run() {
7879
interrupted.set(true);
7980
}
8081
}
81-
}).start();
82+
});
83+
thread.start();
8284

8385
verify(mListener, timeout(2000)).onConnected();
8486

8587
webSocket.interrupt();
86-
Thread.sleep(1000);
88+
89+
thread.join(1000);
90+
91+
assertThat(interrupted.get(), Matchers.is(equalTo(true)));
92+
}
93+
94+
public void testMask() throws Exception {
95+
final WebSocket webSocket = new WebSocket(mListener);
96+
97+
final byte[] src = {0x01, 0x02, 0x03};
98+
final byte[] toMask = src.clone();
99+
final byte[] mask = {0x51, 0x52, 0x53, 0x54};
100+
webSocket.maskBuffer(toMask, mask);
101+
102+
assertThat(toMask, is(not(equalTo(src))));
103+
104+
webSocket.maskBuffer(toMask, mask);
105+
106+
assertThat(toMask, is(equalTo(src)));
107+
108+
}
109+
110+
public void testPing() throws Exception {
111+
final WebSocket webSocket = new WebSocket(mListener);
112+
113+
final AtomicBoolean interrupted = new AtomicBoolean(false);
114+
final Thread thread = new Thread(new Runnable() {
115+
@Override
116+
public void run() {
117+
try {
118+
webSocket.connect(mUri);
119+
} catch (IOException ignore) {
120+
} catch (WrongWebsocketResponse ignore) {
121+
} catch (InterruptedException e) {
122+
interrupted.set(true);
123+
}
124+
}
125+
});
126+
thread.start();
127+
128+
verify(mListener, timeout(2000)).onConnected();
129+
reset(mListener);
130+
final byte[] data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03};
131+
webSocket.sendPingMessage(data.clone());
132+
133+
verify(mListener, timeout(2000)).onPong(data);
134+
135+
webSocket.interrupt();
136+
137+
thread.join(1000);
87138

88139
assertThat(interrupted.get(), Matchers.is(equalTo(true)));
140+
141+
142+
}
143+
144+
public void testReconnection() throws Exception {
145+
final WebSocket webSocket = new WebSocket(mListener);
146+
final Thread thread1 = new Thread(new Runnable() {
147+
@Override
148+
public void run() {
149+
try {
150+
webSocket.connect(mUri);
151+
} catch (IOException ignore) {
152+
} catch (WrongWebsocketResponse ignore) {
153+
} catch (InterruptedException ignore) {
154+
}
155+
}
156+
});
157+
thread1.start();
158+
159+
verify(mListener, timeout(2000)).onConnected();
160+
reset(mListener);
161+
webSocket.interrupt();
162+
thread1.join(1000);
163+
164+
165+
final Thread thread2 = new Thread(new Runnable() {
166+
@Override
167+
public void run() {
168+
try {
169+
webSocket.connect(mUri);
170+
} catch (IOException ignore) {
171+
} catch (WrongWebsocketResponse ignore) {
172+
} catch (InterruptedException ignore) {
173+
}
174+
}
175+
});
176+
thread2.start();
177+
178+
verify(mListener, timeout(2000)).onConnected();
179+
reset(mListener);
180+
webSocket.interrupt();
181+
thread2.join(1000);
89182
}
90183

91184
public void testSendData() throws Exception {
@@ -98,7 +191,7 @@ public void testRequestUsers() throws Exception {
98191
final WebSocket webSocket = authorize();
99192

100193
webSocket.sendStringMessage("{\"action\": \"observe\", \"users\": [12354]}");
101-
verify(mListener, timeout(2000)).onStringMessage(argThat(containsString("\"12354\"")));
194+
verify(mListener, timeout(2000)).onStringMessage(argThat(containsString("\"1235664\"")));
102195

103196
webSocket.interrupt();
104197
}

AndroidSocketIO/src/main/java/com/appunite/websocket/WebSocket.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,30 @@ public void sendByteMessage(byte[] buffer) throws IOException,
277277
sendMessage(OPCODE_BINARY_FRAME, generateMask(), buffer);
278278
}
279279

280+
/**
281+
* Send ping request (thread safe). Can be called after onConnect and
282+
* before onDisconnect by any thread. Thread will be blocked until send
283+
*
284+
* @param buffer
285+
* buffer to send
286+
* @throws IOException
287+
* when exception occur while sending
288+
* @throws InterruptedException
289+
* when user call disconnect
290+
* @throws NotConnectedException
291+
* when called before onConnect or after onDisconnect
292+
*/
293+
@SuppressWarnings("UnusedDeclaration")
294+
public void sendPingMessage(byte[] buffer) throws IOException,
295+
InterruptedException, NotConnectedException {
296+
sendMessage(OPCODE_PING_FRAME, generateMask(), buffer);
297+
}
298+
299+
private void sendPongMessage(byte[] buffer) throws IOException,
300+
InterruptedException, NotConnectedException {
301+
sendMessage(OPCODE_PONG_FRAME, generateMask(), buffer);
302+
}
303+
280304
/**
281305
* Send text message (thread safe). Can be called after onConnect and before
282306
* onDisconnect by any thread. Thread will be blocked until send
@@ -416,6 +440,7 @@ private void readPayload(boolean fin, int opcode,
416440
long payload_len)
417441
throws WrongWebsocketResponse, IOException, InterruptedException,
418442
NotConnectedException {
443+
419444
if (payload_len > 1024 * 1024 || payload_len < 0) {
420445
throw new WrongWebsocketResponse("too large payload");
421446
}
@@ -427,6 +452,10 @@ private void readPayload(boolean fin, int opcode,
427452
byte[] payload = new byte[(int) payload_len];
428453
mInputStream.readBytesOrThrow(payload);
429454

455+
if (masking_key.isPresent()) {
456+
maskBuffer(payload, masking_key.get());
457+
}
458+
430459
if (opcode == OPCODE_CONTINUED_FRAME) {
431460
// TODO
432461
throw new WrongWebsocketResponse(
@@ -439,16 +468,16 @@ private void readPayload(boolean fin, int opcode,
439468
} else if (opcode == OPCODE_CONNECTION_CLOSE_FRAME) {
440469
mListener.onServerRequestedClose(payload);
441470
} else if (opcode == OPCODE_PONG_FRAME) {
442-
mListener.onPing(payload);
443-
sendMessage(OPCODE_PONG_FRAME, generateMask(), payload);
444-
} else if (opcode == OPCODE_PING_FRAME) {
445471
mListener.onPong(payload);
472+
} else if (opcode == OPCODE_PING_FRAME) {
473+
mListener.onPing(payload);
474+
sendPongMessage(payload);
446475
} else {
447476
mListener.onUnknownMessage(payload);
448477
}
449478
}
450479

451-
/**
480+
/**
452481
* Generate 4 bit random mask to send message (thread safe)
453482
*
454483
* @return 4 bit random mask
@@ -465,7 +494,7 @@ private Optional<byte[]> generateMask() {
465494
* @param mask
466495
* 4 byte length mask to apply
467496
*/
468-
private void maskBuffer(byte[] buffer, byte[] mask) {
497+
void maskBuffer(byte[] buffer, byte[] mask) {
469498
checkNotNull(mask);
470499
checkNotNull(buffer);
471500
checkArgument(mask.length == 4);

0 commit comments

Comments
 (0)