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

Are Ping Pong Control frames supported? #30

Open
raghuveer opened this issue Feb 26, 2021 · 6 comments
Open

Are Ping Pong Control frames supported? #30

raghuveer opened this issue Feb 26, 2021 · 6 comments

Comments

@raghuveer
Copy link

raghuveer commented Feb 26, 2021

I am interested to know if amphp/websocket client responds with pong control frame to the ping control frame from web socket server, as per RFC6455 (https://tools.ietf.org/html/rfc6455#section-5.5)?

While this library is really helpful in sending web socket requests, in sync with amphp/redis library, in the scope of redis pubsub related subscribe method, the web socket connection is getting disconnected in few seconds after connection initiation (if I put websocket client connection code above and outside the while loop of amphp/redis library's subscribe method based code), even though my web socket server is configured to support Ping Pong Control frames.

I didnot use the While statement code of the amphp websocket client since, that blocks the next code (i.e. amphp/redis related channel subscription code), just to test, I did include amphp/websocket client connection code inside the While loop of amphp/redis related subscribe method, when the websocket connection is happening and connection is closing with the close command thereafter.

Is this approach scalable?

please share your thoughts to ensure, I be able to use websocket client connection code once, while using that connection code to send messages to the websocket server @kelunik

thank you

@kelunik
Copy link
Member

kelunik commented Feb 26, 2021

Yes, it does automatically respond to pings. Could you share your code that you think is blocked by the while loop?

@raghuveer
Copy link
Author

raghuveer commented Feb 26, 2021

The following is working code, if I put websocket client's connection inside while loop of amphp/redis related subscribe method

`\Amp\Loop::run(function() use ($channel){

$i = 0;

$subscription = yield $this->subscriber->subscribe($channel);
 
while (yield $subscription->advance()) {

	$subscriberResult = $subscription->getCurrent();
	
	$connection = yield connect('wss://ws-dev.postnub.com:8081');
	
	yield $connection->send($subscriberResult);
	yield $connection->close();
	
	if ($i < 3) {
		yield $connection->send("Ping: " . ++$i);
	} else {
		yield $connection->send("Goodbye!");
	}
	
}

});`

@kelunik
Copy link
Member

kelunik commented Feb 26, 2021

So you want to send all messages from the subscription to the websocket server?

@raghuveer
Copy link
Author

raghuveer commented Feb 26, 2021

Absolutely Yes, the goal is to have multiple websocket servers, and all user published messages will be received by one of the websocket servers, and the received messages will be posted to Redis pubsub, and the messages received through subscription code, will then be pushed to websocket server again using amphp websocket client and the following variations are tried and I have error situations, wherein, messages received from subscription code is not being sent to websocket server

scenario 1: websocket client related while loop is kept above amphp/redis subscription code

\Amp\Loop::run(function() use ($channel){

	$connection = yield connect('wss://ws-dev.postnub.com:8081');
	$i = 0;
	
	while ($message = yield $connection->receive()) {
        /** @var Message $message */
        $payload = yield $message->buffer();
        printf("Received: %s\n", $payload);

        if ($payload === "Goodbye!") {
            $connection->close();
            break;
        }

        yield delay(1000); // Pause the coroutine for 1 second.

        if ($i < 3) {
            yield $connection->send("Ping: " . ++$i);
        } else {
            yield $connection->send("Goodbye!");
        }
    }
	

	$subscription = yield $this->subscriber->subscribe($channel);
	 
	while (yield $subscription->advance()) {
	
		$subscriberResult = $subscription->getCurrent();
		
		$connection = yield connect('wss://ws-dev.postnub.com:8081');
		
		yield $connection->send($subscriberResult);
		yield $connection->close();
		
		if ($i < 3) {
			yield $connection->send("Ping: " . ++$i);
		} else {
			yield $connection->send("Goodbye!");
		}
		
	}

});

Scenario 2: Subscription code placed inside while loop of websocket client's while loop

\Amp\Loop::run(function() use ($channel){

	$connection = yield connect('wss://ws-dev.postnub.com:8081');
	$i = 0;
	
	while ($message = yield $connection->receive()) {
        /** @var Message $message */
        $payload = yield $message->buffer();
        printf("Received: %s\n", $payload);

        if ($payload === "Goodbye!") {
            $connection->close();
            break;
        }
		
		$subscription = yield $this->subscriber->subscribe($channel);
	 
		while (yield $subscription->advance()) {
		
			$subscriberResult = $subscription->getCurrent();
			
			$connection = yield connect('wss://ws-dev.postnub.com:8081');
			
			yield $connection->send($subscriberResult);
			yield $connection->close();
			
			if ($i < 3) {
				yield $connection->send("Ping: " . ++$i);
			} else {
				yield $connection->send("Goodbye!");
			}
			
		}

        yield delay(1000); // Pause the coroutine for 1 second.

        if ($i < 3) {
            yield $connection->send("Ping: " . ++$i);
        } else {
            yield $connection->send("Goodbye!");
        }
    }
});

scenario 3: had more issued when I used RatchetPawl websocket client before trying Amphp websocket client

@kelunik
Copy link
Member

kelunik commented Feb 26, 2021

@raghuveer Tip: Use three backticks + php and then a new line to format code, see Creating and highlighting code blocks.

The main problem seems to be that you don't know you can have multiple coroutines, not only the one created from the callable passed to Loop::run().

\Amp\Loop::run(function() use ($channel){
	$connection = yield connect('wss://ws-dev.postnub.com:8081');

    // Use Amp\call and handle errors if you want
    Amp\asyncCall(function () use ($connection) {
		while ($message = yield $connection->receive()) {
	         /** @var Message $message */
	         $payload = yield $message->buffer();
	         printf("Received: %s\n", $payload);
	  
	         if ($payload === "Goodbye!") {
	             $connection->close();
	             break;
	         }
	     }
	});
	
    Amp\asyncCall(function () use ($connection) {
		$i = 0;

		while (true) {
			yield delay(1000); // Pause the coroutine for 1 second.
	  
	        if ($i < 3) {
	            yield $connection->send("Ping: " . ++$i);
	        } else {
	            yield $connection->send("Goodbye!");
				break;
	        }
		}
	});

	$subscription = yield $this->subscriber->subscribe($channel);

	while (yield $subscription->advance()) {
		yield $connection->send($subscription->getCurrent());		
	}
});

@raghuveer
Copy link
Author

raghuveer commented Feb 26, 2021

I am new to using coroutines

Thanks a lot @kelunik for sharing the code sample,

will try this and share the update soon

UPDATE: The code is working flawlessly now.

hope this websocket connection, from amphp websocket client stays active irrespective of whether messages arrive in or not, like redis pubsub persistent connection know

Thanks a lot

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

No branches or pull requests

2 participants