Я использую dll websocket в своем приложении Windows для получения сообщений с сервера GDAX. Пока все работает нормально - сообщения приходят и я их обрабатываю. Точка, в которой я застрял, - это когда сообщения перестают приходить. По крайней мере, я ничего не нахожу в событии WebSocket.OnMessage(https://github.com/sta/websocket-sharp), которые могут помочь мне отслеживать, когда сообщения останавливаются (я также пробовал эмитировать)
Теперь сообщения, которые я получил, имеют тип сообщения «Сердцебиение», которое отправляется каждую секунду. Я хочу добавить отдельный элемент управления таймером, чтобы проверять, приходят ли сообщения пульса каждую секунду или нет, и если они перестанут приходить, мне нужно будет снова подключить сервер. Но поскольку ничего не происходит, когда сообщения перестают приходить, как мне это отслеживать, где я должен поместить код таймера, чтобы проверить, когда перестанут приходить сообщения пульса?
Я надеюсь, что смог объяснить ситуацию, в которой я поражен. Если кто-то хочет помочь мне и нуждается в дополнительных материалах, пожалуйста, дайте мне знать.
Обновить
private void _3_Load(object sender, EventArgs e)
{
ConnectAndGetWebsocketFeedMessages();
}
public delegate void WSOpen(string text);
public delegate void WSMessage(string message);
public delegate void WSError(string text);
public delegate void WSClose(string text);
private static string _endPoint = "wss://ws-feed.gdax.com";
WebSocket ws = new WebSocket(_endPoint);
private bool IsConnected { get; set; }
private string ProductId { get; set; }
string productId = "LTC-EUR";
ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
public void SetWebSocketSharpEvents()
{
ws.Log.Level = LogLevel.Trace;
ws.OnOpen += (sender, e) =>
{
IsConnected = true;
OnWSOpen("Connection Status :: Connected *********");
};
ws.EmitOnPing = true;
ws.OnMessage += (sender, e) =>
{
if (e.IsPing)
{
OnWSMessage("ping received");
}
else
{
OnWSMessage(e.Data);
}
};
ws.OnError += (sender, e) =>
{
IsConnected = false;
OnWSError(e.Message); //An exception has occurred during an OnMessage event. An error has occurred in closing the connection.
if (ws.IsAlive)
ws.Close();
};
ws.OnClose += (sender, e) =>
{
IsConnected = false;
OnWSClose("Close");
};
ws.ConnectAsync();
}
private void ConnectAndGetWebsocketFeedMessages()
{
SetWebSocketSharpEvents();
}
private void SubscribeProduct(string sProductID)
{
if (IsConnected)
{
ProductId = sProductID;
string data = "{\"type\": \"subscribe\", \"product_ids\": [\"" + sProductID + "\"]}";
ws.Send(data);
ws.Send("{\"type\": \"heartbeat\", \"on\": true}");
}
}
void OnWSOpen(string text)
{
SubscribeProduct(productId);
timer1.Interval = 1000;
timer1.Tick += timer1_Tick;
timer1.Start();
}
DateTime lastHeartbeatTime = DateTime.MinValue;
bool isTimerStart = false;
void OnWSMessage(string message)
{
concurrentQueue.Enqueue(message);
SaveHeartbeatMessageTime(message);
ProcessMessage(message);
}
private void SaveHeartbeatMessageTime(string jsonString)
{
var jToken = JToken.Parse(jsonString);
var typeToken = jToken["type"];
var type = typeToken.ToString();
if (type == "heartbeat")
{
lastHeartbeatTime = DateTime.Now;
this.Invoke(new MethodInvoker(delegate()
{
lbllastheartbeat.Text = lastHeartbeatTime.ToLongTimeString();
}));
}
}
private void ProcessMessage(string message) { }
void OnWSError(string text) { }
void OnWSClose(string text) { }
bool isMessagesReceived = false;
private void timer1_Tick(object sender, EventArgs e) // it stops working as soon as lbllastheartbeat gets some value
{
DateTime currentTime = DateTime.Now;
TimeSpan duration = currentTime.Subtract(lastHeartbeatTime);
this.Invoke(new MethodInvoker(delegate()
{
lblNow.Text = currentTime.ToLongTimeString();
}));
if (Int16.Parse(duration.ToString("ss")) > 1)
{
// reconnect here
}
}
Изменить Я использую элемент управления таймером формы Windows, и он продолжает вызывать метод timer1_Tick и не вызывает метод OnWSMessage. Как я могу гарантировать, что оба работают параллельно, и если какое-либо сообщение пропущено или сообщение перестает поступать, оно снова подключается?
Edit2 В приведенных ниже решениях предлагается добавить функцию таймера в событие onMessage, но что произойдет, если я не буду получать сообщения? Если сообщения не получены, код ничего не делает. Я взял глобальную переменную, и всякий раз, когда приходит сообщение, оно добавляет время в эту переменную. Теперь я хочу запустить отдельный элемент управления таймером, который будет проверять, есть ли что-нибудь в этой переменной, и если ее значение, то есть разница в секундах, больше 1, то продолжайте проверять что-то еще.
Есть ли кто-нибудь, кто может изучить это и посоветовать, пожалуйста.
Update2: я все еще хочу сделать это с помощью элемента управления windows.timer, а не threading.timer. Я взял две метки в своем приложении для Windows: lbllastheartbeat (чтобы показать время, когда получено сообщение пульса) и lblNow (чтобы показать текущее время, когда вызывается таймер).
Требование. Мой таймер будет проверять, не пропущено ли какое-либо сообщение пульса, и это делается с помощью переменной lastHeartbeatTime, в которой хранится время получения сообщения пульса.
Я был бы признателен, если бы кто-нибудь мог просмотреть мой код и предложить, что или где я делаю неправильно.
OnMessage
, которое возникает при получении сообщения. В этом случае вы можете остановить таймер, обработать сообщение и перезапустить таймер. Если вы установите таймерInterval
на одну секунду (или любое другое максимальное время между сообщениями, указывающее на то, что сообщения не были отправлены), то событие таймераElapsed
(илиTick
) будет таким, когда вы будете знать, что ни одно сообщение не было получено в течение одной секунды. второй. - person Rufus L   schedule 07.11.2017