Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        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();
        }
Ejemplo n.º 4
0
        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();
        }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
        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;
        }