private bool Connect() { status = NatsMessagingStatus.CONNECTING; bool rv = false; for (ushort i = 1; NatsMessagingStatus.CONNECTING == status && i <= ConnectionAttemptRetries; ++i) { try { tcpClient = new TcpClient(natsHost, natsPort) { NoDelay = true, }; rv = true; break; } catch (SocketException ex) { if (SocketError.ConnectionRefused == ex.SocketErrorCode || SocketError.TimedOut == ex.SocketErrorCode) { log.Error(Resources.NatsClient_ConnectFailed_Fmt, i, ConnectionAttemptRetries); Thread.Sleep(Seconds_10); continue; } else { status = NatsMessagingStatus.ERROR; rv = false; break; } } } if (rv) { currentParseState = ParseState.AWAITING_CONTROL_LINE; log.Debug(Resources.NatsClient_ConnectSuccess_Fmt, natsHost, natsPort); status = NatsMessagingStatus.RUNNING; SendConnectMessage(); } else { log.Error(Resources.NatsClient_ConnectionFailed_Fmt, natsHost, natsPort); status = NatsMessagingStatus.ERROR; } return(rv); }
public void Stop() { if (shuttingDown) { throw new InvalidOperationException(Resources.NatsClient_AttemptingStopTwice_Message); } status = NatsMessagingStatus.STOPPING; shuttingDown = true; CloseNetworking(); var tasks = new List <Task>(); if (null != pollTask) { tasks.Add(pollTask); } if (null != messageProcessorTask) { tasks.Add(messageProcessorTask); } log.Debug(Resources.NatsClient_WaitingForTasks_Message); if (false == tasks.IsNullOrEmpty()) { try { Task.WaitAll(tasks.ToArray()); } catch (AggregateException ex) { foreach (Exception inner in ex.Flatten().InnerExceptions) { log.Error(ex); } } } log.Debug(Resources.NatsClient_Disconnected_Message); status = NatsMessagingStatus.STOPPED; }
private void Poll() { if (shuttingDown) { return; } byte[] readBuffer = new byte[tcpClient.ReceiveBufferSize]; // These are for the current message string subject = null; int subscriptionID = 0; int needed = 0; string inboxID = null; StringBuilder messageBuffer = null; while (false == shuttingDown) { if (NatsMessagingStatus.RUNNING != status && NatsMessagingStatus.CONNECTING != status) { // Shutting down break; } ReceiveMoreData: bool interrupted = false, disconnected = false; if (null == messageBuffer) { messageBuffer = new StringBuilder(); } try { do { int bytesRead = tcpClient.Read(readBuffer); messageBuffer.Append(Encoding.ASCII.GetString(readBuffer, 0, bytesRead)); }while (tcpClient.DataAvailable()); } catch (InvalidOperationException ex) { log.Error(ex, Resources.NatsClient_DisconnectedInPoll_Message); disconnected = true; } catch (IOException ex) { interrupted = HandleException(ex, SocketError.Interrupted); disconnected = false == interrupted; } if (disconnected && false == shuttingDown) { if (false == Reconnect()) { log.Error(Resources.NatsClient_CouldNotReconnect_Message); status = NatsMessagingStatus.ERROR; break; } } if (interrupted && shuttingDown) { // Blocking call was canceled break; } if (messageBuffer.Length > 0) { while (null != messageBuffer) { string incomingData = messageBuffer.ToString(); log.Trace("Parsing: '{0}'", incomingData); switch (currentParseState) { case ParseState.AWAITING_CONTROL_LINE: { if (MSG.IsMatch(incomingData)) { Match match = MSG.Match(incomingData); incomingData = match.Postmatch(incomingData); GroupCollection groups = match.Groups; if (groups.Count > 0) { subject = groups[1].Value; subscriptionID = Convert.ToInt32(groups[2].Value, CultureInfo.InvariantCulture); inboxID = groups[4].Value; needed = Convert.ToInt32(groups[5].Value, CultureInfo.InvariantCulture); currentParseState = ParseState.AWAITING_MSG_PAYLOAD; } } else if (OK.IsMatch(incomingData)) { Match match = OK.Match(incomingData); incomingData = match.Postmatch(incomingData); } else if (ERR.IsMatch(incomingData)) { Match match = ERR.Match(incomingData); incomingData = match.Postmatch(incomingData); GroupCollection groups = match.Groups; if (groups.Count > 0) { string errorData = match.Groups[1].Value; log.Info(Resources.NatsClient_NatsErrorReceived_Fmt, errorData); } } else if (PING.IsMatch(incomingData)) { Write(PongResponse); Match match = PING.Match(incomingData); incomingData = match.Postmatch(incomingData); } else if (PONG.IsMatch(incomingData)) { // TODO: callbacks? Match match = PONG.Match(incomingData); incomingData = match.Postmatch(incomingData); } else if (INFO.IsMatch(incomingData)) { Match match = INFO.Match(incomingData); incomingData = match.Postmatch(incomingData); GroupCollection groups = match.Groups; if (groups.Count > 0) { string infoData = groups[1].Value; log.Info(Resources.NatsClient_NatsInfoReceived_Fmt, infoData); } } else if (UNKNOWN.IsMatch(incomingData)) { Match match = UNKNOWN.Match(incomingData); incomingData = match.Postmatch(incomingData); log.Error(Resources.NatsClient_NatsUnknownReceived_Fmt, match.Value); } else { // If we are here we do not have a complete line yet that we understand. goto ReceiveMoreData; } messageBuffer.Clear(); messageBuffer.Append(incomingData); if (0 == messageBuffer.Length) { messageBuffer = null; } } break; case ParseState.AWAITING_MSG_PAYLOAD: { if (messageBuffer.Length < (needed + CRLFLen)) { goto ReceiveMoreData; } else { string message = messageBuffer.ToString(0, needed); var receivedMessage = new ReceivedMessage(subject, subscriptionID, inboxID, message); lock (messageQueue) { messageQueue.Enqueue(receivedMessage); messageQueuedEvent.Set(); } int startIndex = needed + CRLFLen; int length = messageBuffer.Length - startIndex; string remaining = messageBuffer.ToString(startIndex, length); if (remaining.Length > 0) { messageBuffer = new StringBuilder(remaining); } else { messageBuffer = null; } // NB: do resets last inboxID = String.Empty; subscriptionID = 0; needed = 0; currentParseState = ParseState.AWAITING_CONTROL_LINE; } } break; } } } } messageQueuedEvent.Set(); }
private void Poll() { if (shuttingDown) { return; } byte[] readBuffer = new byte[tcpClient.ReceiveBufferSize]; // These are for the current message string subject = null; int subscriptionID = 0; int needed = 0; string inboxID = null; StringBuilder messageBuffer = null; while (false == shuttingDown) { if (NatsMessagingStatus.RUNNING != status && NatsMessagingStatus.CONNECTING != status) { // Shutting down break; } ReceiveMoreData: bool interrupted = false, disconnected = false; if (null == messageBuffer) { messageBuffer = new StringBuilder(); } try { do { int bytesRead = tcpClient.Read(readBuffer); messageBuffer.Append(Encoding.ASCII.GetString(readBuffer, 0, bytesRead)); } while (tcpClient.DataAvailable()); } catch (InvalidOperationException ex) { log.Error(ex, Resources.NatsMessagingProvider_DisconnectedInPoll_Message); disconnected = true; } catch (IOException ex) { interrupted = HandleException(ex, SocketError.Interrupted); disconnected = false == interrupted; } if (disconnected && false == shuttingDown) { if (false == Reconnect()) { log.Fatal(Resources.NatsMessagingProvider_CouldNotReconnect_Message); status = NatsMessagingStatus.ERROR; break; } } if (interrupted && shuttingDown) { // Blocking call was canceled break; } if (messageBuffer.Length > 0) { while (null != messageBuffer) { string incomingData = messageBuffer.ToString(); log.Trace("Parsing: '{0}'", incomingData); switch (currentParseState) { case ParseState.AWAITING_CONTROL_LINE: { if (MSG.IsMatch(incomingData)) { Match match = MSG.Match(incomingData); incomingData = match.Postmatch(incomingData); GroupCollection groups = match.Groups; if (groups.Count > 0) { subject = groups[1].Value; subscriptionID = Convert.ToInt32(groups[2].Value, CultureInfo.InvariantCulture); inboxID = groups[4].Value; needed = Convert.ToInt32(groups[5].Value, CultureInfo.InvariantCulture); currentParseState = ParseState.AWAITING_MSG_PAYLOAD; } } else if (OK.IsMatch(incomingData)) { Match match = OK.Match(incomingData); incomingData = match.Postmatch(incomingData); } else if (ERR.IsMatch(incomingData)) { Match match = ERR.Match(incomingData); incomingData = match.Postmatch(incomingData); GroupCollection groups = match.Groups; if (groups.Count > 0) { string errorData = match.Groups[1].Value; log.Info(Resources.NatsMessagingProvider_NatsErrorReceived_Fmt, errorData); } } else if (PING.IsMatch(incomingData)) { Write(PongResponse); Match match = PING.Match(incomingData); incomingData = match.Postmatch(incomingData); } else if (PONG.IsMatch(incomingData)) { // TODO: callbacks? Match match = PONG.Match(incomingData); incomingData = match.Postmatch(incomingData); } else if (INFO.IsMatch(incomingData)) { Match match = INFO.Match(incomingData); incomingData = match.Postmatch(incomingData); GroupCollection groups = match.Groups; if (groups.Count > 0) { string infoData = groups[1].Value; log.Info(Resources.NatsMessagingProvider_NatsInfoReceived_Fmt, infoData); } } else if (UNKNOWN.IsMatch(incomingData)) { Match match = UNKNOWN.Match(incomingData); incomingData = match.Postmatch(incomingData); log.Error(Resources.NatsMessagingProvider_NatsUnknownReceived_Fmt, match.Value); } else { // If we are here we do not have a complete line yet that we understand. goto ReceiveMoreData; } messageBuffer.Clear(); messageBuffer.Append(incomingData); if (0 == messageBuffer.Length) { messageBuffer = null; } } break; case ParseState.AWAITING_MSG_PAYLOAD: { if (messageBuffer.Length < (needed + CRLFLen)) { goto ReceiveMoreData; } else { string message = messageBuffer.ToString(0, needed); var receivedMessage = new ReceivedMessage(subject, subscriptionID, inboxID, message); lock (messageQueue) { messageQueue.Enqueue(receivedMessage); messageQueuedEvent.Set(); } int startIndex = needed + CRLFLen; int length = messageBuffer.Length - startIndex; string remaining = messageBuffer.ToString(startIndex, length); if (remaining.Length > 0) { messageBuffer = new StringBuilder(remaining); } else { messageBuffer = null; } // NB: do resets last inboxID = String.Empty; subscriptionID = 0; needed = 0; currentParseState = ParseState.AWAITING_CONTROL_LINE; } } break; } } } } messageQueuedEvent.Set(); }
private bool Connect() { status = NatsMessagingStatus.CONNECTING; bool rv = false; for (ushort i = 1; NatsMessagingStatus.CONNECTING == status && i <= ConnectionAttemptRetries; ++i) { try { tcpClient = new TcpClient(natsHost, natsPort) { LingerState = new LingerOption(true, 0), NoDelay = true }; rv = true; break; } catch (SocketException ex) { if (SocketError.ConnectionRefused == ex.SocketErrorCode || SocketError.TimedOut == ex.SocketErrorCode) { log.Error(Resources.NatsMessagingProvider_ConnectFailed_Fmt, i, ConnectionAttemptRetries); Thread.Sleep(Seconds_10); continue; } else { status = NatsMessagingStatus.ERROR; rv = false; break; } } } if (rv) { currentParseState = ParseState.AWAITING_CONTROL_LINE; log.Debug(Resources.NatsMessagingProvider_ConnectSuccess_Fmt, natsHost, natsPort); status = NatsMessagingStatus.RUNNING; SendConnectMessage(); } else { log.Fatal(Resources.NatsMessagingProvider_ConnectionFailed_Fmt, natsHost, natsPort); status = NatsMessagingStatus.ERROR; } return rv; }
public void Stop() { if (shuttingDown) { throw new InvalidOperationException(Resources.NatsMessagingProvider_AttemptingStopTwice_Message); } status = NatsMessagingStatus.STOPPING; shuttingDown = true; CloseNetworking(); var tasks = new List<Task>(); if (null != pollTask) { tasks.Add(pollTask); } if (null != messageProcessorTask) { tasks.Add(messageProcessorTask); } log.Debug(Resources.NatsMessagingProvider_WaitingForTasks_Message); if (false == tasks.IsNullOrEmpty()) { try { Task.WaitAll(tasks.ToArray()); } catch (AggregateException ex) { foreach (Exception inner in ex.Flatten().InnerExceptions) { log.Error(ex); } } } log.Debug(Resources.NatsMessagingProvider_Disconnected_Message); status = NatsMessagingStatus.STOPPED; }