public override Task Send(IConnection connection, string data, string connectionData) { if (connection == null) { throw new ArgumentNullException("connection"); } var webSocket = _webSocket; if (webSocket == null) { Exception ex; if (connection.State != ConnectionState.Disconnected) { // Make this a faulted task and trigger the OnError even to maintain consistency with the HttpBasedTransports ex = new InvalidOperationException(ResourcesStore.GetResourceString("Error_DataCannotBeSentDuringWebSocketReconnect")); connection.OnError(ex); } else { ex = new InvalidOperationException(ResourcesStore.GetResourceString("Error_DataCannotBeSentDuringWebSocketReconnect")); } var tcs = new DispatchingTaskCompletionSource <object>(); tcs.SetException(ex); return(tcs.Task); } return(Send(webSocket, data)); }
private void ResolveTransport(IConnection connection, string data, CancellationToken disconnectToken, DispatchingTaskCompletionSource <object> tcs, int index) { // Pick the current transport IClientTransport transport = _transports[index]; transport.Start(connection, data, disconnectToken).ContinueWith(task => { if (task.IsFaulted || task.IsCanceled) { Exception ex; if (task.IsCanceled) { ex = new OperationCanceledException(Resources.Error_TaskCancelledException); } else { ex = task.Exception.GetBaseException(); } connection.Trace(TraceLevels.Events, "Auto: Failed to connect to using transport {0}. {1}", transport.Name, ex); // If that transport fails to initialize, then fallback. // If it is that /start request that failed, do not fallback. var next = index + 1; if (next < _transports.Count && !(ex is StartException)) { // Try the next transport ResolveTransport(connection, data, disconnectToken, tcs, next); } else { // If there's nothing else to try then just fail tcs.SetException(ex); } } else { // Set the active transport _transport = transport; // Complete the process tcs.SetResult(null); } }, TaskContinuationOptions.ExecuteSynchronously); }