hyperf icon indicating copy to clipboard operation
hyperf copied to clipboard

[QUESTION] How can I communicate between HTTP server and WebSocket Server?

Open bosunski opened this issue 1 year ago • 3 comments

Before you submit an issue, please be sure to search through existing issues as well as search through the documentation

  • [x] I've searched all existing issues
  • [x] I've read all relevant documentation I could find

Describe your question

I have my Hyperf application serving both HTTP and WebSocket traffics. The WebSocket maintains a list of client connections in-memory. I would want to have an HTTP endpoint that returns the number of clients that are connected. Is there a way to achieve this without having to store data out of the application (e.g. Redis, MySQL, etc).

I was hoping there is a way the HTTP and the WebSocket server can establish communication since they are basically within the same app. If so, how can I achieve this? If not, what are your recommendations / alternatives for this?

Thank you very much!

bosunski avatar Oct 03 '24 21:10 bosunski

It just idea, but maybe you can try

ApplicationContext::getContainer()
            ->get(ServerFactory::class)
            ->getServer()
            ->getServer()
            ->stats();

and receive swoole server stat with active connections parameter.

I could be wrong, but WS connection is not really differs from other connections (just http request with upgrade header), and there is few issues with it, how you split http connections from ws and if you have few workers, ws connections could spread between them, so you will require redis or processes communication in this situation i think

volodymyr-hordiienko avatar Oct 03 '24 21:10 volodymyr-hordiienko

Thanks for the response @volodymyr-hordiienko. I actually need more than getting the stats. I want both ends to communicate in realtime.

To be more specific, the WebSocket has an InstanceStorage object that stores a list of Instance objects. This instance storage is bound in the container. For the start, the intent is to expose an API, such that when called, will return the number of objects in the InstanceStorage.

When I resolved the InstanceStorage from the container, in the HTTP controller, the list of objects is empty, even when they aren't. Later I will like to send some data recieved from the HTTP controller down to these objects, but that isn't even possible since the list is empty.

I expect that the objects will be there, but I'm sure there's a key piece I'm missing on how Hyperf/Swoole works in a case like this.

But I hope this give more insight into when I'm trying to do.

bosunski avatar Oct 03 '24 23:10 bosunski

Probably InstanceObject are not singleton object, as workaround you can store shared data in swoole table https://openswoole.com/docs/4.x/modules/swoole-table

praswicaksono avatar Oct 05 '24 12:10 praswicaksono


use Hyperf\Server\ServerManager;
use Hyperf\Server\ServerInterface;

function getActiveFds() {
/** @var Port $server */
foreach (ServerManager::list() as [$type, $server]) {
    foreach (ServerManager::list() as [$type, $server]) {
        if ($type == ServerInterface::SERVER_WEBSOCKET) {
            $fds = iterator_to_array($server->connections);
        }
    }
}



billythekids avatar Nov 23 '24 18:11 billythekids