Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ping message #119

Open
dinos19 opened this issue Aug 19, 2022 · 3 comments
Open

ping message #119

dinos19 opened this issue Aug 19, 2022 · 3 comments

Comments

@dinos19
Copy link

dinos19 commented Aug 19, 2022

Hello , ive noticed that native websocket client is using keep-alive as an interval to send unsolicited pongs.
I was asked to change that and send ping instead. I've done some research but i could not find anything useful. Is there any way to send ping frames and control the pong frames i receive ?

@Jericho
Copy link

Jericho commented Oct 12, 2022

I have a similar scenario: the 3rd-party system I connect to requires me to send a specific message every 30 seconds to keep the connection alive and it does not support the standard ping/pong. I was able to achieve this by turning off the built-in ping/pong and sending a "heartbeat" every 30 seconds like so:

var clientFactory = new Func<Uri, CancellationToken, Task<WebSocket>>(async (uri, cancellationToken) =>
{
	// The current value in the uri parameter must be ignored because it contains "access_token" which may or may not be expired.
	// The following line ensures the "access_token" is refreshed whenever it expires.
	uri = new Uri($"wss://ws.zoom.us/ws?subscriptionId={_subscriptionId}&access_token={_tokenHandler.Token}");

	var client = new ClientWebSocket()
	{
		Options =
		{
			KeepAliveInterval = TimeSpan.Zero, // Turn off built-in "Keep Alive" feature because Zoom uses proprietary "heartbeat" every 30 seconds rather than standard "pong" messages at regular interval.
		}
	};

	await client.ConnectAsync(uri, cancellationToken).ConfigureAwait(false);
	return client;
});

// Please note that the url specified on the following line will be ignored and will be replaced with the URI calculated in the client factory
_websocketClient = new WebsocketClient(new Uri("wss://ws.zoom.us"), clientFactory);
_websocketClient.Name = "ZoomNet";
_websocketClient.ReconnectTimeout = TimeSpan.FromSeconds(45); // Greater than 30 seconds because we send a heartbeat every 30 seconds
_websocketClient.ErrorReconnectTimeout = TimeSpan.FromSeconds(45);
_websocketClient.ReconnectionHappened.Subscribe(info => _logger.LogTrace($"Reconnection happened, type: {info.Type}"));
_websocketClient.DisconnectionHappened.Subscribe(info => _logger.LogTrace($"Disconnection happened, type: {info.Type}"));
_websocketClient.MessageReceived.Subscribe(ProcessMessage);

Task.Run(() => SendHeartbeat(_websocketClient));

and the heartbeat method is defined like so:

private async Task SendHeartbeat(IWebsocketClient client)
{
	while (true)
	{
		await Task.Delay(TimeSpan.FromSeconds(30)); // Zoom requires a heartbeat every 30 seconds

		if (!client.IsRunning)
		{
			continue;
		}

		client.Send("{\"module\":\"heartbeat\"}"); // <-- This is the specific message I must send every 30 seconds. 
	}
}

Hope this helps

@dinos19
Copy link
Author

dinos19 commented Oct 13, 2022

Im using aws apigateaway websocket in conjuction with aws lambda to create the websocket api. The problem is that aws apigateaway doesn't ping the clients to keep track of the connected clients. So the client should be in charge of maintaining the connection. But the library for the websocket client sends only unsolicited pongs to keep alive the connection. This is a valid way to keep alive the connection but the client doesn't have any clue if the connection is alive or not. So I need to send pings from the client and not pongs, so when i receive the pong from aws apigateaway i can confirm in the client side that the connection is alive. Sending a random heartbeat message is not an option since aws apigateaway will count it as a regular message and I will be charged for it. So I can only use the regular ping/pong.

@Jericho
Copy link

Jericho commented Oct 13, 2022

To my knowledge Microsoft's ClientWebSocket does not allow you to send "ping" frames, only "text" and "binary". Therefore, I don't think you'll be able to achieve what you are trying to do, whether you use this library or any other library that relies on System.Net.WebSockets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants