Improve AppRTCDemo connection speed by sending all

http POST requests asynchronously.

R=jiayl@webrtc.org, tkchin@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/33499004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7820 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
glaznev@webrtc.org 2014-12-05 20:11:06 +00:00
parent bd8cc0b914
commit e2a9261f3e

View File

@ -26,7 +26,6 @@
*/
package org.appspot.apprtc;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@ -36,7 +35,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedList;
import java.util.Scanner;
import org.appspot.apprtc.RoomParametersFetcher.RoomParametersFetcherEvents;
@ -64,6 +62,9 @@ public class WebSocketRTCClient implements AppRTCClient,
private enum ConnectionState {
NEW, CONNECTED, CLOSED, ERROR
};
private enum MessageType {
MESSAGE, BYE
};
private final Handler uiHandler;
private boolean loopback;
private boolean initiator;
@ -71,14 +72,12 @@ public class WebSocketRTCClient implements AppRTCClient,
private WebSocketChannelClient wsClient;
private RoomParametersFetcher fetcher;
private ConnectionState roomState;
private LinkedList<PostMessage> postQueue;
private String postMessageUrl;
private String byeMessageUrl;
public WebSocketRTCClient(SignalingEvents events) {
this.events = events;
uiHandler = new Handler(Looper.getMainLooper());
postQueue = new LinkedList<PostMessage>();
}
// --------------------------------------------------------------------
@ -222,8 +221,9 @@ public class WebSocketRTCClient implements AppRTCClient,
Log.d(TAG, "Disconnect. Room state: " + roomState);
if (roomState == ConnectionState.CONNECTED) {
Log.d(TAG, "Closing room.");
sendGAEMessage(byeMessageUrl, "");
sendPostMessage(MessageType.BYE, byeMessageUrl, "");
}
roomState = ConnectionState.CLOSED;
if (wsClient != null) {
wsClient.disconnect();
}
@ -236,10 +236,14 @@ public class WebSocketRTCClient implements AppRTCClient,
// we might want to filter elsewhere.
@Override
public void sendOfferSdp(final SessionDescription sdp) {
if (roomState != ConnectionState.CONNECTED) {
reportError("Sending offer SDP in non connected state.");
return;
}
JSONObject json = new JSONObject();
jsonPut(json, "sdp", sdp.description);
jsonPut(json, "type", "offer");
sendGAEMessage(postMessageUrl, json.toString());
sendPostMessage(MessageType.MESSAGE, postMessageUrl, json.toString());
if (loopback) {
// In loopback mode rename this offer to answer and route it back.
SessionDescription sdpAnswer = new SessionDescription(
@ -279,7 +283,7 @@ public class WebSocketRTCClient implements AppRTCClient,
reportError("Sending ICE candidate in non connected state.");
return;
}
sendGAEMessage(postMessageUrl, json.toString());
sendPostMessage(MessageType.MESSAGE, postMessageUrl, json.toString());
if (loopback) {
events.onRemoteIceCandidate(candidate);
}
@ -317,50 +321,36 @@ public class WebSocketRTCClient implements AppRTCClient,
}
private class PostMessage {
PostMessage(String postUrl, String message) {
PostMessage(MessageType type, String postUrl, String message) {
this.messageType = type;
this.postUrl = postUrl;
this.message = message;
}
public final MessageType messageType;
public final String postUrl;
public final String message;
}
// Queue a message for sending to the room and send it if already connected.
private synchronized void sendGAEMessage(String url, String message) {
synchronized (postQueue) {
postQueue.add(new PostMessage(url, message));
private synchronized void sendPostMessage(
MessageType messageType, String url, String message) {
final PostMessage postMessage = new PostMessage(messageType, url, message);
Runnable runDrain = new Runnable() {
public void run() {
sendPostMessageAsync(postMessage);
}
(new AsyncTask<Void, Void, Void>() {
public Void doInBackground(Void... unused) {
maybeDrainGAEPostQueue();
return null;
}
}).execute();
};
new Thread(runDrain).start();
}
// Send all queued messages if connected to the room.
private void maybeDrainGAEPostQueue() {
if (roomState != ConnectionState.CONNECTED) {
return;
}
PostMessage postMessage = null;
while (true) {
synchronized (postQueue) {
postMessage = postQueue.poll();
}
if (postMessage == null) {
break;
}
try {
// Check if this is 'bye' message and update room connection state.
if (postMessage.postUrl.contains("bye")) {
roomState = ConnectionState.CLOSED;
// Send all queued POST messages to app engine server.
private void sendPostMessageAsync(PostMessage postMessage) {
if (postMessage.messageType == MessageType.BYE) {
Log.d(TAG, "C->GAE: " + postMessage.postUrl);
} else {
Log.d(TAG, "C->GAE: " + postMessage.message);
}
try {
// Get connection.
HttpURLConnection connection =
(HttpURLConnection) new URL(postMessage.postUrl).openConnection();
@ -387,7 +377,7 @@ public class WebSocketRTCClient implements AppRTCClient,
InputStream responseStream = connection.getInputStream();
String response = drainStream(responseStream);
responseStream.close();
if (roomState != ConnectionState.CLOSED) {
if (postMessage.messageType == MessageType.MESSAGE) {
JSONObject roomJson = new JSONObject(response);
String result = roomJson.getString("result");
if (!result.equals("SUCCESS")) {
@ -400,7 +390,6 @@ public class WebSocketRTCClient implements AppRTCClient,
reportError("GAE POST JSON error: " + e.getMessage());
}
}
}
// Return the contents of an InputStream as a String.
private String drainStream(InputStream in) {