RejectedSoftware Forums

Sign up

Forcing a websocket ping/pong

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Re: Forcing a websocket ping/pong

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

There are two existing examples:

https://github.com/vibe-d/vibe-http/tree/master/examples/websocket
https://vibed.org/blog/posts/a-scalable-chat-room-service-in-d

In particular, the first example could be extended with a client-side part roughly like this:

connectWebSocket("http://127.0.0.1:8080/ws", (scope ws) {
	while (ws.waitForData) {
		auto message = ws.receiveText();
		logInfo("Received message from server: %s", message);
		ws.send("PONG");
	}
});

The complete example then looks like this:

module app;

import vibe.core.core;
import vibe.core.log;
import vibe.http.fileserver : serveStaticFiles;
import vibe.http.router : URLRouter;
import vibe.http.server;
import vibe.http.websockets : WebSocket, handleWebSockets, connectWebSocket;
import vibe.inet.url : URL;

import core.time;
import std.conv : to;


int main(string[] args)
{
	auto router = new URLRouter;
	router.get("/", staticRedirect("/index.html"));
	router.get("/ws", handleWebSockets(&handleWebSocketConnection));
	router.get("*", serveStaticFiles("public/"));

	auto settings = new HTTPServerSettings;
	settings.port = 8080;
	settings.bindAddresses = ["::1", "127.0.0.1"];

	auto listener = listenHTTP(settings, router);

	// connect to the web socket endpoint and reply to all messages received
	runTask({
		try connectWebSocket(URL("http://127.0.0.1:8080/ws"), (scope socket) {
			while (socket.waitForData) {
				auto message = socket.receiveText();
				logInfo("Received message from server: %s", message);
				socket.send("PONG");
			}
		});
		catch (Exception e) logException(e, "Failed to connect web socket");
	});

	return runApplication(&args);
}

void handleWebSocketConnection(scope WebSocket socket)
{
	int counter = 0;
	logInfo("Got new web socket connection.");

	// read replies as long as the connection is active
	runTask({
		try {
			while (socket.waitForData) {
				auto message = socket.receiveText();
				logInfo("Received message from client: %s", message);
			}
		} catch (Exception e) logException(e, "Failed to receive web socket message");
	});

	while (true) {
		sleep(1.seconds);
		if (!socket.connected) break;
		counter++;
		logInfo("Sending '%s'.", counter);
		socket.send(counter.to!string);
	}
	logInfo("Client disconnected.");
}

The send and receive operations can be separated into different loops running in different tasks, as on the server side here, or can be made is sequence, as on the client side, depending on what the protocol requires.

Re: Forcing a websocket ping/pong

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Since there a similar ticket just popped up, in case this is actually meant to send a low-level ping/pong on the web socket protocol level, this might be relevant: https://github.com/vibe-d/vibe.d/issues/2802

Re: Forcing a websocket ping/pong

On Tue, 04 Jun 2024 08:58:05 GMT, Sönke Ludwig wrote:

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Since there a similar ticket just popped up, in case this is actually meant to send a low-level ping/pong on the web socket protocol level, this might be relevant: https://github.com/vibe-d/vibe.d/issues/2802

This is exactly the same request, thanks.

Re: Forcing a websocket ping/pong

On Tue, 04 Jun 2024 08:58:05 GMT, Sönke Ludwig wrote:

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Since there a similar ticket just popped up, in case this is actually meant to send a low-level ping/pong on the web socket protocol level, this might be relevant: https://github.com/vibe-d/vibe.d/issues/2802

module app;

import vibe.core.core;
import vibe.core.log;
import vibe.http.fileserver : serveStaticFiles;
import vibe.http.router : URLRouter;
import vibe.http.server;
import vibe.web.web;
import vibe.http.websockets;
import vibe.vibe;


int main(string[] args)
{
	string WS_URL= "wss://echo.websocket.org";
	auto ws_url = URL(WS_URL);
	const use_tls = (ws_url.schema == "wss" || ws_url.schema == "https") ? true : false;
    ws_url.schema = use_tls ? "https" : "http";
    auto receiver = connectWebSocket(ws_url);
	
	
	ConnectionStream m_conn;
	RandomNumberStream m_rng;
	
	auto message = new OutgoingWebSocketMessage(m_conn, FrameOpcode.ping, m_rng);

	while (receiver.waitForData())
	 {
			auto msg = parseJsonString(receiver.receiveText());
			
			try {
					ws.send((message) { message.write([]); }, FrameOpcode.ping);
				}
				catch (Exception ex)
				{
					logInfo("error %s", ex.msg);
				}
			logInfo("%s", msg);
	    }
	
	return 0;
}

This does not work:
source/app.d(30,17): Error: class vibe.http.websockets.OutgoingWebSocketMessage constructor this is not accessible
source/app.d(39,32): Error: none of the overloads of write are callable using argument types ()

Do you have an example that works?

Re: Forcing a websocket ping/pong

On Tue, 04 Jun 2024 15:33:51 GMT, MrX wrote:

On Tue, 04 Jun 2024 08:58:05 GMT, Sönke Ludwig wrote:

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Since there a similar ticket just popped up, in case this is actually meant to send a low-level ping/pong on the web socket protocol level, this might be relevant: https://github.com/vibe-d/vibe.d/issues/2802

module app;

import vibe.core.core;
import vibe.core.log;
import vibe.http.fileserver : serveStaticFiles;
import vibe.http.router : URLRouter;
import vibe.http.server;
import vibe.web.web;
import vibe.http.websockets;
import vibe.vibe;


int main(string[] args)
{
	string WS_URL= "wss://echo.websocket.org";
	auto ws_url = URL(WS_URL);
	const use_tls = (ws_url.schema == "wss" || ws_url.schema == "https") ? true : false;
    ws_url.schema = use_tls ? "https" : "http";
    auto receiver = connectWebSocket(ws_url);
	
	
	ConnectionStream m_conn;
	RandomNumberStream m_rng;
	
	auto message = new OutgoingWebSocketMessage(m_conn, FrameOpcode.ping, m_rng);

	while (receiver.waitForData())
	 {
			auto msg = parseJsonString(receiver.receiveText());
			
			try {
					ws.send((message) { message.write([]); }, FrameOpcode.ping);
				}
				catch (Exception ex)
				{
					logInfo("error %s", ex.msg);
				}
			logInfo("%s", msg);
	    }
	
	return 0;
}

This does not work:
source/app.d(30,17): Error: class vibe.http.websockets.OutgoingWebSocketMessage constructor this is not accessible
source/app.d(39,32): Error: none of the overloads of write are callable using argument types ()

Do you have an example that works?

Sorry receiver.send((message) { message.write([]); }, FrameOpcode.ping); typo fix.

Re: Forcing a websocket ping/pong

On Tue, 04 Jun 2024 15:35:21 GMT, MrX wrote:

On Tue, 04 Jun 2024 15:33:51 GMT, MrX wrote:

On Tue, 04 Jun 2024 08:58:05 GMT, Sönke Ludwig wrote:

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Since there a similar ticket just popped up, in case this is actually meant to send a low-level ping/pong on the web socket protocol level, this might be relevant: https://github.com/vibe-d/vibe.d/issues/2802

(...)

This does not work:
source/app.d(30,17): Error: class vibe.http.websockets.OutgoingWebSocketMessage constructor this is not accessible
source/app.d(39,32): Error: none of the overloads of write are callable using argument types ()

Do you have an example that works?

Sorry receiver.send((message) { message.write([]); }, FrameOpcode.ping); typo fix.

The following compiles and runs successfully for me, the explicit OutgoingWebSocketMessage construction wasn't being used and could just be removed. The remaining error was caused by .write having two overloads (const(char)[] and const(ubyte)[]) that were ambiguous:

import vibe.core.core;
import vibe.core.log;
import vibe.http.fileserver : serveStaticFiles;
import vibe.http.router : URLRouter;
import vibe.http.server;
import vibe.http.websockets;
import vibe.inet.url;
import core.time;


int main(string[] args)
{
    string WS_URL= "wss://echo.websocket.org";
    auto ws_url = URL(WS_URL);
    const use_tls = (ws_url.schema == "wss" || ws_url.schema == "https") ? true : false;
    ws_url.schema = use_tls ? "https" : "http";
    auto receiver = connectWebSocket(ws_url);
    
    while (receiver.waitForData())
     {
            logInfo("GOT: %s", receiver.receiveText());
            
            try {
                    receiver.send((message) { message.write(""); }, FrameOpcode.ping);
            }
            catch (Exception ex) {
                logInfo("error %s", ex.msg);
            }

            sleep(2.seconds);
            receiver.send("hello!");
        }
    
    return 0;
}

Re: Forcing a websocket ping/pong

On Thu, 06 Jun 2024 13:39:59 GMT, Sönke Ludwig wrote:

On Tue, 04 Jun 2024 15:35:21 GMT, MrX wrote:

On Tue, 04 Jun 2024 15:33:51 GMT, MrX wrote:

On Tue, 04 Jun 2024 08:58:05 GMT, Sönke Ludwig wrote:

On Tue, 28 May 2024 12:19:26 GMT, MrX wrote:

Hello,

Could someone share an example on how to execute a ping/pong through a WebSocket?

Thank you.

Since there a similar ticket just popped up, in case this is actually meant to send a low-level ping/pong on the web socket protocol level, this might be relevant: https://github.com/vibe-d/vibe.d/issues/2802

(...)

This does not work:
source/app.d(30,17): Error: class vibe.http.websockets.OutgoingWebSocketMessage constructor this is not accessible
source/app.d(39,32): Error: none of the overloads of write are callable using argument types ()

Do you have an example that works?

Sorry receiver.send((message) { message.write([]); }, FrameOpcode.ping); typo fix.

The following compiles and runs successfully for me, the explicit OutgoingWebSocketMessage construction wasn't being used and could just be removed. The remaining error was caused by .write having two overloads (const(char)[] and const(ubyte)[]) that were ambiguous:

import vibe.core.core;
import vibe.core.log;
import vibe.http.fileserver : serveStaticFiles;
import vibe.http.router : URLRouter;
import vibe.http.server;
import vibe.http.websockets;
import vibe.inet.url;
import core.time;


int main(string[] args)
{
    string WS_URL= "wss://echo.websocket.org";
    auto ws_url = URL(WS_URL);
    const use_tls = (ws_url.schema == "wss" || ws_url.schema == "https") ? true : false;
    ws_url.schema = use_tls ? "https" : "http";
    auto receiver = connectWebSocket(ws_url);
    
    while (receiver.waitForData())
     {
            logInfo("GOT: %s", receiver.receiveText());
            
            try {
                    receiver.send((message) { message.write(""); }, FrameOpcode.ping);
            }
            catch (Exception ex) {
                logInfo("error %s", ex.msg);
            }

            sleep(2.seconds);
            receiver.send("hello!");
        }
    
    return 0;
}

This works! Thanks.