Exemplo n.º 1
0
        void HeartbeatRoutine(object a_worker)
        {
            Worker worker = (Worker)a_worker;
            ProtocolType protocol = worker.m_socket.ProtocolType;
            IPEndPoint dest;
            if (protocol == ProtocolType.Udp) {
                dest = m_subServerAddr_udp;
                worker.m_poller.Start(worker.m_socket);
            }
            else {
                Debug.Assert(protocol == ProtocolType.Tcp);
                dest = m_subServerAddr_tcp;
            }

            Heartbeat heartbeat = new Heartbeat(GetName(worker.m_socket));

            Message ping = new Message();
            int pingPongCtx = 0;
            ping.m_contextSeq = 1;
            ping.m_contextID = pingPongCtx;

            string errComment = "";
            while (m_run) {
                heartbeat.WaitForInterval(errComment);

                ping.m_pingTime = System.Environment.TickCount;

                bool succeedPing = false;
                switch (protocol) {
                    case ProtocolType.Tcp:
                        if (worker.m_poller.IsRegstered(worker.m_socket))
                            succeedPing = worker.m_poller.Send(worker.m_socket, ping, true);
                        else {
                            if (ping.m_contextSeq > 1) {
                                ping.m_contextSeq = 1;
                                worker.m_socket.Close();
                                worker.m_socket = Function.CreateSocket(ProtocolType.Tcp,
                                                                        null,
                                                                        false);
                            }
                            succeedPing = worker.m_poller.ConnectAndSend(worker.m_socket, dest, ping);
                        }
                        break;

                    case ProtocolType.Udp:
                        succeedPing = worker.m_poller.SendTo(worker.m_socket, dest, ping, true);
                        break;

                    default:
                        Debug.Assert(false);
                        break;
                }
                if (succeedPing == false) {
                    errComment = "failed request.";
                    heartbeat.Timeout();
                    continue;
                }

                Message pong;
                Socket sock;
                IPEndPoint sender;
                bool isTimeout = ! worker.m_poller.WaitForMessage(Config.Response_Timeout_Ms,
                                                                  out pong,
                                                                  out sock,
                                                                  out sender);
                if (isTimeout) {
                    errComment = "response timeout.";
                    heartbeat.Timeout();
                    continue;
                }

                if (pong.m_contextID != pingPongCtx) {
                    heartbeat.Timeout();
                    errComment = "wrong message.";
                    Config.OnErrorDelegate("잘못된 메시지를 수신 : " + pong.ToString());
                    continue;
                }

                heartbeat.Reset();

                if (ping.AddressIsEmpty()) {
                    ping.m_address = pong.m_address;
                    ping.m_port = pong.m_port;
                }

                ++ping.m_contextSeq;
            }
        }