package com.zsoft.SignalA.Transport.Longpolling;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.json.JSONObject;
import android.util.Log;
import com.turbomanage.httpclient.AsyncCallback;
import com.turbomanage.httpclient.HttpResponse;
import com.turbomanage.httpclient.ParameterMap;
import com.zsoft.SignalA.ConnectionBase;
import com.zsoft.SignalA.ConnectionState;
import com.zsoft.SignalA.SignalAUtils;
import com.zsoft.SignalA.SendCallback;
import com.zsoft.SignalA.Transport.ProcessResult;
import com.zsoft.SignalA.Transport.TransportHelper;
import com.zsoft.parallelhttpclient.ParallelHttpClient;
public class ConnectedState extends StopableStateWithCallback {
protected static final String TAG = "ConnectedState";
private Object mCallbackLock = new Object();
//@SuppressWarnings("unused")
//private AjaxCallback<JSONObject> mCurrentCallback = null;
public ConnectedState(ConnectionBase connection) {
super(connection);
}
@Override
public ConnectionState getState() {
return ConnectionState.Connected;
}
@Override
public void Start() {
}
@Override
public void Stop() {
mConnection.SetNewState(new DisconnectingState(mConnection));
super.Stop();
}
@Override
public void Send(final CharSequence text, final SendCallback sendCb) {
if(DoStop())
{
sendCb.OnError(new Exception("Connection is about to close"));
return;
}
String url = SignalAUtils.EnsureEndsWith(mConnection.getUrl(), "/");
url += "send?transport=" + TRANSPORT_NAME;
try {
url += "&connectionToken=" + URLEncoder.encode(mConnection.getConnectionToken(), "utf-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported message encoding error, when encoding connectionToken.");
}
TransportHelper.AppendCustomQueryString(mConnection, url);
AsyncCallback cb = new AsyncCallback()
{
@Override
public void onComplete(HttpResponse httpResponse)
{
if(httpResponse.getStatus() == 200)
{
Log.v(TAG, "Message sent: " + text);
sendCb.OnSent(text);
JSONObject json = JSONHelper.ToJSONObject(httpResponse.getBodyAsString());
if(json!=null && json.length()>0)
{
mConnection.setMessage(json);
}
}
else
{
Exception ex = new Exception("Error sending message");
mConnection.setError(ex);
sendCb.OnError(ex);
}
}
@Override
public void onError(Exception ex) {
mConnection.setError(ex);
sendCb.OnError(ex);
}
};
ParallelHttpClient httpClient = new ParallelHttpClient();
ParameterMap params = httpClient.newParams()
.add("data", text.toString());
httpClient.setMaxRetries(1);
httpClient.post(url, params, cb);
}
@Override
protected void OnRun() {
if(DoStop()) return;
String baseUrl = SignalAUtils.EnsureEndsWith(mConnection.getUrl(), "/");
String url = "";
if (mConnection.getMessageId() == null || mConnection.getMessageId().length()==0)
{
url += "connect";
}
else
{
url += "poll";
}
// url += TransportHelper.GetReceiveQueryString(mConnection, null, TRANSPORT_NAME);
String connectionData = mConnection.OnSending();
url += TransportHelper.GetReceiveQueryString(mConnection, connectionData, TRANSPORT_NAME);
AsyncCallback cb = new AsyncCallback() {
@Override
public void onComplete(HttpResponse httpResponse) {
if(DoStop()) return;
try
{
if(httpResponse != null && httpResponse.getStatus() == 200)
{
JSONObject json = JSONHelper.ToJSONObject(httpResponse.getBodyAsString());
if (json!=null)
{
ProcessResult result = TransportHelper.ProcessResponse(mConnection, json);
if(result.processingFailed)
{
mConnection.setError(new Exception("Error while proccessing response."));
mConnection.SetNewState(new ReconnectingState(mConnection));
}
else if(result.disconnected)
{
mConnection.SetNewState(new DisconnectedState(mConnection));
return;
}
}
else
{
mConnection.setError(new Exception("Error when calling endpoint. Returncode: " + httpResponse.getStatus()));
mConnection.SetNewState(new ReconnectingState(mConnection));
}
}
else
{
mConnection.setError(new Exception("Error when calling endpoint."));
mConnection.SetNewState(new ReconnectingState(mConnection));
}
}
finally
{
mIsRunning.set(false);
// Loop if we are still connected
if(mConnection.getCurrentState() == ConnectedState.this)
Run();
}
}
@Override
public void onError(Exception ex) {
mConnection.setError(ex);
mConnection.SetNewState(new ReconnectingState(mConnection));
}
};
synchronized (mCallbackLock) {
//mCurrentCallback = cb;
}
ParallelHttpClient httpClient = new ParallelHttpClient(baseUrl);
httpClient.setMaxRetries(1);
httpClient.setConnectionTimeout(5000);
httpClient.setReadTimeout(115000);
ParameterMap params = httpClient.newParams();
httpClient.post(url, params, cb);
}
}