package com.koushikdutta.async.http.socketio.transport; import android.net.Uri; import android.net.Uri.Builder; import com.koushikdutta.async.AsyncServer; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.http.AsyncHttpClient; import com.koushikdutta.async.http.AsyncHttpGet; import com.koushikdutta.async.http.AsyncHttpPost; import com.koushikdutta.async.http.AsyncHttpRequest; import com.koushikdutta.async.http.AsyncHttpResponse; import com.koushikdutta.async.http.body.StringBody; public class XHRPollingTransport implements SocketIOTransport { private AsyncHttpClient client; private Uri sessionUrl; private StringCallback stringCallback; private CompletedCallback closedCallback; private boolean connected; private String sessionId; private static final String SEPARATOR = "\ufffd"; public XHRPollingTransport(AsyncHttpClient client, String sessionUrl, String sessionId) { this.client = client; this.sessionUrl = Uri.parse(sessionUrl); this.sessionId = sessionId; doLongPolling(); connected = true; } @Override public boolean isConnected() { return connected; } @Override public void setClosedCallback(CompletedCallback handler) { closedCallback = handler; } @Override public void disconnect() { connected = false; close(null); } private void close(Exception ex) { if (closedCallback != null) closedCallback.onCompleted(ex); } @Override public AsyncServer getServer() { return client.getServer(); } @Override public void send(String message) { if (message.startsWith("5")) { postMessage(message); return; } AsyncHttpRequest request = new AsyncHttpPost(computedRequestUrl()); request.setBody(new StringBody(message)); client.executeString(request, new AsyncHttpClient.StringCallback() { @Override public void onCompleted(Exception e, AsyncHttpResponse source, String result) { if (e != null) { close(e); return; } sendResult(result); } }); } private void postMessage(String message) { if (!message.startsWith("5")) return; AsyncHttpRequest request = new AsyncHttpPost(computedRequestUrl()); request.setBody(new StringBody(message)); client.executeString(request, null); } private void doLongPolling() { this.client.executeString(new AsyncHttpGet(computedRequestUrl()), new AsyncHttpClient.StringCallback() { @Override public void onCompleted(Exception e, AsyncHttpResponse source, String result) { if (e != null) { close(e); return; } sendResult(result); doLongPolling(); } }); } private void sendResult(String result) { if (stringCallback == null) return; if (!result.contains(SEPARATOR)) { stringCallback.onStringAvailable(result); return; } String [] results = result.split(SEPARATOR); for (int i = 1; i < results.length; i = i + 2) { stringCallback.onStringAvailable(results[i+1]); } } /** * Return an url with a time-based parameter to avoid caching issues */ private String computedRequestUrl() { String currentTime = String.valueOf(System.currentTimeMillis()); return sessionUrl.buildUpon().appendQueryParameter("t", currentTime) .build().toString(); } @Override public void setStringCallback(StringCallback callback) { stringCallback = callback; } @Override public boolean heartbeats() { return false; } @Override public String getSessionId() { return this.sessionId; } }