com.yy.httpproxy.requester.SocketIoRequester Maven / Gradle / Ivy
package com.yy.httpproxy.requester;
import android.os.Handler;
import android.util.Base64;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.yy.httpproxy.AndroidLoggingHandler;
import com.yy.httpproxy.proxy.Request;
import org.json.JSONObject;
import java.lang.reflect.Type;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class SocketIoRequester implements HttpRequester {
private static String TAG = "ProxyClient";
private Map replyCallbacks = new HashMap();
private Handler handler = new Handler();
private Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new JsonDeserializer() {
@Override
public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return json == null ? null : new Date(json.getAsLong());
}
}).registerTypeAdapter(Date.class, new JsonSerializer() {
@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
return src == null ? new JsonPrimitive(0l) : new JsonPrimitive(src.getTime());
}
}).create();
private Runnable timeoutTask = new Runnable() {
@Override
public void run() {
Iterator> it = replyCallbacks.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = it.next();
Request request = pair.getValue();
if (request.timeoutForRequest()) {
Log.i(TAG, "StompClient timeoutForRequest " + request.getRequestInfo().getUrl());
if (request.getResponseHandler() != null) {
request.getResponseHandler().onError(new RequestException(null, RequestException.Error.TIMEOUT_ERROR));
}
it.remove();
continue;
}
}
handler.removeCallbacks(this);
handler.postDelayed(this, 1000);
}
};
private int sequenceId;
private final Emitter.Listener httpProxyListener = new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
Log.i("", "response" + data.optString("response"));
int responseSeqId = data.optInt("sequenceId", 0);
int statusCode = data.optInt("statusCode", 0);
String response = data.optString("response", "no response body from server");
Request request = replyCallbacks.remove(responseSeqId);
if (request != null && request.getResponseHandler() != null) {
request.getResponseHandler().onSuccess(null, statusCode, null);
}
}
};
private Socket mSocket;
public SocketIoRequester(String host) {
AndroidLoggingHandler.reset(new AndroidLoggingHandler());
java.util.logging.Logger.getLogger("").setLevel(Level.FINEST);
try {
IO.Options opts = new IO.Options();
opts.transports = new String[]{"websocket"};
mSocket = IO.socket(host, opts);
mSocket.on("httpProxy", httpProxyListener);
mSocket.connect();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
@Override
public void request(RequestInfo requestInfo, ResponseHandler handler) {
JSONObject object = new JSONObject();
JSONObject headers = new JSONObject();
try {
if (!mSocket.connected()) {
handler.onError(new RequestException(null, RequestException.Error.CONNECT_ERROR));
return;
}
sequenceId = sequenceId + 1;
if (requestInfo.getHeaders() != null) {
for (Map.Entry header : requestInfo.getHeaders().entrySet()) {
headers.put(header.getKey(), header.getValue());
}
}
object.put("headers", headers);
JSONObject options = new JSONObject();
options.put("method", "POST");
object.put("body", Base64.encode(requestInfo.getBody(), Base64.DEFAULT));
object.put("url", requestInfo.getUrl());
object.put("sequenceId", String.valueOf(sequenceId));
Request request = new Request(requestInfo, handler);
replyCallbacks.put(sequenceId, request);
mSocket.emit("httpProxy", object);
} catch (Exception e) {
handler.onError(new RequestException(e, RequestException.Error.CLIENT_DATA_SERIALIZE_ERROR));
}
}
}