Task c_MessageReceived(Turbocharged.NSQ.Message obj) { var data = BitConverter.ToString(obj.Body, 0); var message = string.Format("RECEIVED MESSAGE. Id = {0}, Msg = {1}", obj.Id, data); PostMessage(message); return(Task.FromResult(0)); }
void WorkerLoop(object messageHandler) { MessageHandler handler = (MessageHandler)messageHandler; bool firstConnectionAttempt = true; TcpClient client = null; FrameReader reader = null; IBackoffLimiter backoffLimiter = null; IDisposable cancellationRegistration = Disposable.Empty; while (true) { try { if (_connectionClosedSource.IsCancellationRequested) { return; } if (!Connected) { lock (_connectionSwapLock) { if (firstConnectionAttempt) { firstConnectionAttempt = false; } else { if (backoffLimiter == null) backoffLimiter = _backoffStrategy.Create(); TimeSpan delay; if (backoffLimiter.ShouldReconnect(out delay)) { OnInternalMessage("Delaying {0} ms before reconnecting", (int)delay.TotalMilliseconds); Thread.Sleep(delay); } else { // We give up OnInternalMessage("Abandoning connection"); Dispose(); return; } } lock (_connectionSwapInProgressLock) { CancellationToken cancellationToken; lock (_disposeLock) { if (_disposed) return; if (client != null) { cancellationRegistration.Dispose(); ((IDisposable)client).Dispose(); } cancellationToken = _connectionClosedSource.Token; } OnInternalMessage("TCP client starting"); client = new TcpClient(_endPoint.Host, _endPoint.Port); cancellationRegistration = cancellationToken.Register(() => ((IDisposable)client).Dispose(), false); Connected = true; OnInternalMessage("TCP client started"); _stream = client.GetStream(); reader = new FrameReader(_stream); Handshake(_stream, reader); _firstConnection.TrySetResult(true); // Start a new backoff cycle next time we disconnect backoffLimiter = null; _nextReconnectionTaskSource.SetResult(true); _nextReconnectionTaskSource = new TaskCompletionSource<bool>(); } } } Frame frame; while ((frame = reader.ReadFrame()) != null) { if (frame.Type == FrameType.Result) { if (HEARTBEAT.SequenceEqual(frame.Data)) { OnInternalMessage("Heartbeat"); SendCommandAsync(new Nop()) .ContinueWith(t => Dispose(), TaskContinuationOptions.OnlyOnFaulted); } else { OnInternalMessage("Received result. Length = {0}", frame.MessageSize); } } else if (frame.Type == FrameType.Message) { OnInternalMessage("Received message. Length = {0}", frame.MessageSize); var message = new Message(frame, this); // TODO: Rethink this ThreadPool.QueueUserWorkItem(new WaitCallback(_ => { handler(message); })); } else if (frame.Type == FrameType.Error) { string errorString; try { errorString = Encoding.ASCII.GetString(frame.Data); } catch { errorString = BitConverter.ToString(frame.Data); } OnInternalMessage("Received error. Message = {0}", errorString); } else { OnInternalMessage("Unknown message type: {0}", frame.Type); throw new InvalidOperationException("Unknown message type " + frame.Type); } } } catch (ObjectDisposedException ex) { OnInternalMessage("Exiting worker loop due to disposal. Message = {0}", ex.Message); Connected = false; return; } catch (IOException ex) { if (!_disposed) OnInternalMessage("EXCEPTION: {0}", ex.Message); Connected = false; continue; } catch (SocketException ex) { if (!_disposed) OnInternalMessage("EXCEPTION: {0}", ex.Message); Connected = false; continue; } } }