在 hyperf 框架中,websocket 可以创建一个公共的定时器,定时器可以 websocket push 消息

想实现这样的一个功能,举个例子。例如:赛马游戏:每80秒开奖,开奖后发送群推消息,推送给所有人或一部分人。然后玩家可以在任意时间连接 websocket,在连接时返回 定时器 剩余的时间。

我想使用 hyperf 框架来实现类似这种业务,在 hyperf 框架启动后,创建一个共用的定时器,在规定时间向所有或者一部分连接的 fd 推送消息,然后客户端连接 websocket 后 服务端 推送 定时器的时间 和其他的消息给客户端。

我使用的是 hyperf 封装好 hyperf/websocket-server,但是貌似只能针对当前的 websocket fd 连接来创建定时器,而且没有 websocket 连接的话控制器内的方法也没有调用,在自定义进程 写内重新写 WebSocketServer 也不可以,请问有人遇到过这样的问题或者解决的思路吗?谢谢了

最佳答案

你的意思是指定fd发送消息吧?

ws连接成功后,需要自己维护下fd与userId的关系,比如存进redis。

然后,看下↓这个文件,对你应该有帮助。

/vendor/hyperf/websocket-server/src/Sender.php

我在app/Kernel/Functions.php加了这两个方法。

然后通过composer的autoload利用files载进来,这样就可以当做全局方法使用了。

composer.json

"autoload": {
    "psr-4": {
      "App\\": "app/"
    },
    "files": [
      "app/Kernel/Functions.php"
    ]
  },

app/Kernel/Functions.php

if (!function_exists('di')) {
    /**
     * Finds an entry of the container by its identifier and returns it.
     * @param null|mixed $id
     * @return mixed|\Psr\Container\ContainerInterface
     */
    function di($id = null)
    {
        $container = ApplicationContext::getContainer();
        if ($id) {
            return $container->get($id);
        }
        return $container;
    }
}

if (!function_exists('ws_send')) {
    /**
     * Send websocket message
     * @param int $fd
     * @param $data
     * @param int $opcode
     * @param bool $finish
     */
    function ws_send(int $fd, string $data, int $opcode = 1, bool $finish = true)
    {
        /** @var \Hyperf\WebSocketServer\Sender $sender */
        $sender = di(Sender::class);
        $sender->push($fd, $data, $opcode, $finish);
    }
}

在你想要push的地方,调用ws_send(ws的fd,你的数据);

如果你是想要做广播或群发消息,一样的道理,遍历对应的fd就是了。

4年前 评论
heyroc (楼主) 4年前
讨论数量: 1

你的意思是指定fd发送消息吧?

ws连接成功后,需要自己维护下fd与userId的关系,比如存进redis。

然后,看下↓这个文件,对你应该有帮助。

/vendor/hyperf/websocket-server/src/Sender.php

我在app/Kernel/Functions.php加了这两个方法。

然后通过composer的autoload利用files载进来,这样就可以当做全局方法使用了。

composer.json

"autoload": {
    "psr-4": {
      "App\\": "app/"
    },
    "files": [
      "app/Kernel/Functions.php"
    ]
  },

app/Kernel/Functions.php

if (!function_exists('di')) {
    /**
     * Finds an entry of the container by its identifier and returns it.
     * @param null|mixed $id
     * @return mixed|\Psr\Container\ContainerInterface
     */
    function di($id = null)
    {
        $container = ApplicationContext::getContainer();
        if ($id) {
            return $container->get($id);
        }
        return $container;
    }
}

if (!function_exists('ws_send')) {
    /**
     * Send websocket message
     * @param int $fd
     * @param $data
     * @param int $opcode
     * @param bool $finish
     */
    function ws_send(int $fd, string $data, int $opcode = 1, bool $finish = true)
    {
        /** @var \Hyperf\WebSocketServer\Sender $sender */
        $sender = di(Sender::class);
        $sender->push($fd, $data, $opcode, $finish);
    }
}

在你想要push的地方,调用ws_send(ws的fd,你的数据);

如果你是想要做广播或群发消息,一样的道理,遍历对应的fd就是了。

4年前 评论
heyroc (楼主) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!