private void OpenConnection(IConnection connection,
string data,
Action initializeCallback,
Action<Exception> errorCallback)
{
// If we're reconnecting add /connect to the url
bool _reconnecting = initializeCallback == null;
string _url = (_reconnecting ? connection.Url : connection.Url + "connect");
Action<IRequest> _prepareRequest = PrepareRequest(connection);
EventSignal<IResponse> _signal;
if (shouldUsePost(connection))
{
_url += GetReceiveQueryString(connection, data);
//Debug.WriteLine("ServerSentEventsTransport: POST {0}", _url);
_signal = m_httpClient.PostAsync(
_url,
request =>
{
_prepareRequest(request);
request.Accept = "text/event-stream";
},
new Dictionary<string, string> {
{
"groups", GetSerializedGroups(connection) }
});
}
else
{
_url += GetReceiveQueryStringWithGroups(connection, data);
//Debug.WriteLine("ServerSentEventsTransport: GET {0}", _url);
_signal = m_httpClient.GetAsync(
_url,
request =>
{
_prepareRequest(request);
request.Accept = "text/event-stream";
});
}
_signal.Finished += (sender, e) =>
{
if (e.Result.IsFaulted)
{
Exception _exception = e.Result.Exception.GetBaseException();
if (!HttpBasedTransport.IsRequestAborted(_exception))
{
if (errorCallback != null &&
Interlocked.Exchange(ref m_initializedCalled, 1) == 0)
errorCallback(_exception);
else if (_reconnecting)
// Only raise the error event if we failed to reconnect
connection.OnError(_exception);
}
if (_reconnecting)
{
// Retry
Reconnect(connection, data);
return;
}
}
else
{
// Get the reseponse stream and read it for messages
IResponse _response = e.Result;
Stream _stream = _response.GetResponseStream();
AsyncStreamReader _reader = new AsyncStreamReader(
_stream,
connection,
() =>
{
if (Interlocked.CompareExchange(ref m_initializedCalled, 1, 0) == 0)
initializeCallback();
},
() =>
{
_response.Close();
Reconnect(connection, data);
});
if (_reconnecting)
// Raise the reconnect event if the connection comes back up
connection.OnReconnected();
_reader.StartReading();
// Set the reader for this connection
connection.Items[m_readerKey] = _reader;
}
};
if (initializeCallback != null)
{
int _tryed = 0;
while (true)
{
_tryed++;
//Debug.WriteLine("Checking if connection initialized for the {0} time: ", _tryed.ToString());
Thread.Sleep(m_connectionTimeout);
if (Interlocked.CompareExchange(ref m_initializedCalled, 1, 0) == 0)
{
if (_tryed < m_connectionRetry)
{
//Debug.WriteLine("Connection initialized failed after {0} times.", _tryed.ToString());
continue;
}
//Debug.WriteLine("Giving up on connection initializing.");
Debug.Log("stopping");
// Stop the connection
Stop(connection);
// Connection timeout occurred
errorCallback(new TimeoutException());
break;
}
else
{
//Debug.WriteLine("Connection initialized succeed.");
break;
}
}
}
}