Heartbeat

Created at 08 Nov 2023, 10:24
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
BE

bernhardCM

Joined 06.11.2023

Heartbeat
08 Nov 2023, 10:24


Hello,

according to the documentation https://help.ctrader.com/open-api/connection/ => Best Practices, it should be sent a ProtoHeartbeatEvent every 10 seconds.

I got the samples and my application working, but I'm not sure how to keep the connection alive. The C# samples don't send any ProtoHeartbeatEvent (in my mind), set only “HeardbeatInternal” to 10 seconds by the OpenClient constructor: 

this.Client = new OpenClient(this.Server_ApiHost, this.Server_ApiPort, TimeSpan.FromSeconds(10));

the WinForm-Sampe subscribes to these events, but OnMessage is not called by ProtoHeartbeatEvent

this.Client.ObserveOn(SynchronizationContext.Current).OfType<ProtoMessage>().Subscribe(OnMessage, OnError);

although it is expected by it (OpenApiMessagesPresentation):

switch ((ProtoPayloadType)msg.PayloadType)
{
	//....
	case ProtoPayloadType.HeartbeatEvent:
 		var _hb = ProtoHeartbeatEvent.Parser.ParseFrom(msg.Payload);
 		_str += "Heartbeat";
 		break;

I could figure ProtoHeartbeatEvent out by adding a sbscription particularily to ProtoHeartbeatEvent, OnProtoHeartbeatEvent will be called every 30 seconds:

this.Client.ObserveOn(SynchronizationContext.Current).OfType<ProtoHeartbeatEvent>().Subscribe(OnProtoHeartbeatEvent);

private void OnProtoHeartbeatEvent(ProtoHeartbeatEvent protoHeartbeatEvent)
{
	string sDebug = "";
}

If I send a ProtoHeartbeatEvent from client-side every 5 seconds, OnProtoHeartbeatEvent will keep calling each 30 seconds:

public void Heartbeat()
{
  	ProtoMessage protoHeartbeatEvent = new ProtoMessage
  	{
   			Payload = new ProtoHeartbeatEvent
   			{
   			}.ToByteString(),
   			PayloadType = (int)ProtoPayloadType.HeartbeatEvent
  	};
  	this.SendProtoMessage(protoHeartbeatEvent);
}

private async void SendProtoMessage(ProtoMessage protoMessage)
{
	if (string.IsNullOrWhiteSpace(protoMessage.ClientMsgId)) 
 	protoMessage.ClientMsgId = this.GetGUID();

	await this.Client.SendMessage(protoMessage);
}

wich looks strange, does not meet my client side ProtoHeartbeatEvent sendings each 5 seconds as well not 10 seconds specifiied by the OpenClient constructor. My Heartbeat() method seems to be ignored without any response.

I doubt that the connection will be lost later and would like to know how to make sure that connection will keep alive. Could someone explain how to get OnProtoHeartbeatEvent called each 10 seconds and especially controlled called, so amendable by the client.

 

Thank you so much for your help!

Bernhard

 

 


@bernhardCM
Replies

PanagiotisCharalampous
08 Nov 2023, 12:59 ( Updated at: 09 Nov 2023, 06:30 )

Hi there,

OnProtoHeartbeatEvent checks for incoming heartbeats. If you want to send heartbeats at a specific interval, you should use a Timer.

Best regards


@PanagiotisCharalampous

bernhardCM
09 Nov 2023, 08:32 ( Updated at: 09 Nov 2023, 10:44 )

Hello,

the search function is a bit difficult in this forum :-) sorting by last activity instead of search by “heartbeat” I found that thread: https://ctrader.com/forum/connect-api-support/38894 about the same issue, which states: 

  • I need to send heartbeats each 10 seconds, otherwise connection will be closed after some seconds, but I will not get any notification whether my sent heartbeat has been accepted, or there was maybe any difficulty
  • just need to listen to the OnProtoHeartbeatEvent and whether there arrives a call each 30 seconds as notification that connection is still open - which has nothing to do with my sent heartbeat itself

Is that the correct solution and made I correct by my code above?

Thank you.

Bernhard


@bernhardCM