Программирование сокетов с помощью heartbeat постоянно не синхронизируется - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть устройство, к которому я подключаюсь через ком-порт, и оно имеет 3 функции:

  • Пульс, который я должен подтвердить
  • Проверка состояния
  • Запуск работы устройств

Когда устройство посылает мне пульс, мое следующее сообщение на устройство всегда должно быть подтверждением, иначе устройство не будет отвечать.

Проблема У меня есть то, что время от времени мое приложение будет отправлять команду StartDevice или StatusCheck сразу после получения Heartbeat, и все это развалится

Как мне решить эту проблему?

Ниже я написал простую версию своего кода:

public class MyDevice {

    ComPort comPort;
    Timer statusTimer;

    public MyDevice() {
        //Create a socket connection to the device
        comPort = new ComPort("COM5");
        comPort.Recieve += RecieveSomeData;
        comPort.Open();
        //Start an update timer every 5 mins
        statusTimer = new Timer();
        statusTimer.Tick += StatusTimerTick;
        statusTimer.Start(5);
    }

    public void StartDevice() {
        comPort.Send("Start Device Operation!");
    }

    protected void StatusTimerTick() {
        comPort.Send("What is your status?");
    }

    protected void RecieveSomeData(string data) {
        //if the device sends heart beat, send acknowledgment back
        if (data.StartsWith("Heartbeat")) {
            comPort.Send("Acknowledgement!");
        }
        //if the device is replying to status or 
        // a start operation then tell the consumer
        else {
            ReportStatus(data);
        }
    }

    private void ReportStatus(string data) {
        throw new NotImplementedException();
    }
}

1 Ответ

0 голосов
/ 16 февраля 2019

Протокол, который вы описываете, склонен к гонке.Может случиться, что устройство отправит запрос Heartbeat примерно в то же время, когда ваше приложение отправит StatusTimerTick.В этом случае устройство получит StatusTimerTick до того, как получит ответ на Heartbeat, даже если этот ответ был отправлен сразу после того, как ваша заявка получила Heartbeat.

Единственный способ решить проблему - этоперепроектировать ваш протокол или ожидания.Самый простой редизайн будет означать, что ответ Heartbeat должен по-прежнему следовать за каждым запросом Heartbeat, но между ними могут быть получены некоторые другие сообщения, например StatusTimerTick.Если это слишком сложно, вы можете изменить дизайн протокола так, чтобы ваше приложение отправляло что-то только тогда, когда ваше устройство явно запрашивает информацию, но не само по себе без такого запроса.

...