NetMQ.FiniteStateMachineException: Rep.XRecv - не удается получить другой запрос - PullRequest
0 голосов
/ 29 мая 2019

я постоянно получаю NetMQ.FiniteStateMachineException

конечно, мой код работает ... исключение не происходит сразу ... но в течение нескольких часов, вероятно, это произойдет.

Кто-нибудь знает, что здесь происходит, чтобы вызвать это исключение?

Я не совсем уверен, почему, хотя я прочитал объяснение здесь: c # - ZeroMQ FiniteStateMachineException в шаблоне REQ / REP - Переполнение стека

Я получаю кучу таких:

исключение

NetMQ.FiniteStateMachineException: Rep.XRecv - cannot receive another request
   at NetMQ.Core.Patterns.Rep.XRecv(Msg& msg)
   at NetMQ.Core.SocketBase.TryRecv(Msg& msg, TimeSpan timeout)
   at NetMQ.NetMQSocket.TryReceive(Msg& msg, TimeSpan timeout)
   at NetMQ.ReceivingSocketExtensions.ReceiveFrameString(IReceivingSocket socket, Encoding encoding, Boolean& more)
   at NinjaTrader.NinjaScript.AddOns.anAddOn.ZeroMQ_Server()
NetMQ.FiniteStateMachineException: Rep.XRecv - cannot receive another request
   at NetMQ.Core.Patterns.Rep.XRecv(Msg& msg)
   at NetMQ.Core.SocketBase.TryRecv(Msg& msg, TimeSpan timeout)
   at NetMQ.NetMQSocket.TryReceive(Msg& msg, TimeSpan timeout)
   at NetMQ.ReceivingSocketExtensions.ReceiveFrameString(IReceivingSocket socket, Encoding encoding, Boolean& more)
   at NinjaTrader.NinjaScript.AddOns.anAddOn.ZeroMQ_Server()

мой код


        // thread start code

                if (thread == null) {
                    print2("Addon {0}: is starting, listening on port: {1}...", GetType().Name, ZeroPort);
                    thread = new Thread(ZeroMQ_Server);
                    thread.Start();
                }

        // zeroMQ code

        #region TaskCallBack - NetMQ
        // This thread procedure performs the task.
        private void ZeroMQ_Server()
        { 
            bool quit = false;
            string bindAddress = "tcp://*:"+ZeroPort;
            try {
                while (!quit) {
                    try {
                        using (var repSocket = new ResponseSocket()) 
                        {
                            curRepSocket = repSocket;
                            print2("*** BINDING on {0} ***", bindAddress);
                            repSocket.Bind(bindAddress); 

                            while (!quit) {
                                try {
                                    Running = true;

                                    var msgStr = repSocket.ReceiveFrameString();
                                    print2("[►] {2} [REP:{0}] {1}", bindAddress, msgStr, DateTime.Now.ToString("HH:mm:ss.fff"));
                                    if (processMsg(msgStr)) {
                                        StringBuilder csv = new StringBuilder();
                                        // string building stuff here

                                        string cs = csv.ToString();
                                        print2("[◄] csv: {0}", cs);
                                        repSocket.SendFrame(cs);
                                    } else {
                                        repSocket.SendFrame("Unrecognized Command: " + msgStr);
                                        break;
                                    }

                                } catch (Exception e) {
                                    quit = isThreadAborted(e);
                                }
                            }
                        }

                    } catch (Exception e) {
                        if (e is AddressAlreadyInUseException) {
                            //print2("");
                        } else quit = isThreadAborted(e);
                    } finally {
                        curRepSocket = null;
                        Running = false;
                    }
                }
            } finally {
                //NetMQConfig.Cleanup(); 
            }
        }

        private bool isThreadAborted(Exception e) {
            if (e is ThreadAbortException) {
                print2("\n*** thread aborting... ***");
                return true;
            } else {
                print2(e);
                return false;
            }
        }

1 Ответ

1 голос
/ 29 мая 2019

Ответ сокета является конечным автоматом, вы должны отвечать на каждый запрос.Из кода кажется, что если processMsg выдает, вы ничего не отправляете обратно, поэтому вы не можете получить снова и получить исключение.

Это также может произойти, если отправка не удалась, если клиент ушел.

Попробуйте вместо этого использовать роутер, вот так:

while (true)
{
    bool more;
    var msg = routerSocket.ReceiveFrameBytes(out more);

    // Forwarding the routing id.
    routerSocket.SendMoreFrame(msg);

    // Bottom, next frame is the message
    if (msg.Length == 0)
        break;
}

// Write your handling here

...