耿贤坤 2019-01-07 19:58:04 8666次浏览 6条回复 10 3 0

yii2-websocket 是基于 yii2 实现的 WebSocket 扩展,提供 WebSocket 客户端及 WebSocket 服务端。

底层支持 swooleworkerman 驱动。

workerman的 fd 连接号存在问题,目前推荐使用 swoole 驱动。

为什么需要 WebSocket ?

WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。

了解计算机网络协议的人,应该都知道:HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了 请求/响应 模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步JavaScriptXML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。WebSocket 只需要建立一次连接,就可以一直保持连接状态。这相比于轮询方式的不停建立连接显然效率要大大提高。

yii2-websocket 扩展通过底层 swoole/workerman 驱动实现 WebSocket 服务,并提供了客户端及服务端。

安装

安装此扩展程序的首选方法是通过 composer.

编辑运行

php composer.phar require --prefer-dist yiiplus/yii2-websocket "^1.0.0"

或添加配置到项目目录下的composer.json文件的 require 部分

"yiiplus/yii2-websocket": "^1.0.0"

基本使用

配置
return [
    'bootstrap' => [
        'websocket',
    ],
    'compoents' => [
        'websocket' => [
            'class' => '\yiiplus\websocket\<dirver>\WebSocket',
            'host' => '127.0.0.1',
            'port' => 9501,
            'channels' => [
                'push-message' => '\xxx\channels\PushMessageChannel', // 配置 channel 对应的执行类
            ],
      ],
    ],
];
定义 channel 执行类

每个 channel 的功能都需要定义一个单独的类,WebSocket Server 会通过客户端传来的 channel 参数解析。

例如,如果你需要为所有客户端推送一条消息,则该类可能如下所示:

namespace xxx\channels;

class PushMessageChannel extends BaseObject implements \yiiplus\websocket\ChannelInterface
{
    public function execute($fd, $data)
    {
        return [
            $fd, // 第一个参数返回客户端ID,多个以数组形式返回
            $data->message // 第二个参数返回需要返回给客户端的消息
        ];
    }

    public function close($fd)
    {
        return;
    }
}

定义好的执行类需要注册到 compoents 配置中的 channels 下。

当客户端断开连接时会触发所有 channels 下的 close 方法,用于清理客户端在服务器上与业务的绑定关系。

客户端发送 channel 消息,触发执行类
Yii::$app->websocket->send(['channel' => 'push-message', 'message' => '用户 xxx 送了一台飞机!']);
控制台执行

执行任务的确切方式取决于使用的驱动程序。 大多数驱动程序可以使用控制台命令运行,组件需要在应用程序中注册。

此命令启动一个守护进程,该守护进程维护一个 WebSocket Server,根据客户端发来的数据,处理相关 channel 的任务:

yii websocket/start

资料

觉得很赞
  • 回复于 2020-01-14 11:09 举报

    我服务器那边报missing client data 楼主怎么回事

    2 条回复
    回复于 2020-02-18 17:51 回复

    不好意思,刚看到,用的是swoole的驱动么

    回复于 2020-03-02 16:28 回复

    我也是这样。服务器报错missing client data,用的swoole驱动

  • 回复于 2019-11-21 15:30 举报

    你这个需要安装swoole或者workerman吗

    1 条回复
    回复于 2020-02-18 17:51 回复

    嗯嗯,需要安装的

  • 回复于 2019-08-06 15:39 举报

    楼主!我的mac 命令行 输入这个命令 yii websocket/start 一直报错Unknown command: websocket/start

    1 条回复
    回复于 2019-08-21 19:55 回复

    有可能是因为没有配置bootstrap造成的

  • 回复于 2019-03-19 23:37 举报

    楼主!composer.phar一直报错!之前下载YII框架都没有问题!我从github下载以后不知道文件该放什么位置!能不能详细的说一下!

    1 条回复
    回复于 2019-03-22 15:48 回复

    贴一下详细的报错信息帮你分析一下,有可能是composer-asset-plugin包版本问题。

    最好不要直接下载源码调用,vendor包最好不要被代码仓库追踪。

  • 回复于 2019-01-23 11:15 举报

    楼主 这个能单推消息到 一个用户吗?

    1 条回复
    回复于 2019-01-25 11:29 回复

    当然可以,channel的接口类声明了两个方法,execute close,分别在websocket消息处理阶段和websocket通道结束阶段触发。

    execute方法就是在消息处理阶段被触发的,它接收两个参数,分别是 $fd 客户端连接ID,及 $data 客户端传输来的数据,同时这个方法的返回值需要以数组的形式返回两个参数,第一个就是$fds表示将消息推送到哪个或哪些个客户端上(多个以数组形式返回),第二个参数$data就表示推送给用户的消息了。

    通过这种方式可以实现根据业务灵活的推送消息了,在 https://github.com/yiiplus/yii2-websocket/tree/master/examples 中,实现了一个直播间推送消息的例子,其中通过yii\redis\ActiveRecord 绑定用户与直播间的关系,就可以实现往指定直播间推送消息的功能了。

    另外,在客户端断开连接时会触发所有 channels 下的 close 方法,你可以用来清理客户端在服务器上与业务的绑定关系。在上面的例子代码中也有使用。

    欢迎尝试,现在文档不太完善,有什么问题随时沟通哦~

  • 回复于 2019-01-11 10:33 举报

    不好意思,上面配置描述有误,文章不知为什么没办法修改,将channel 更改为 channels,如下:

    'compoents' => [
        'websocket' => [
            'class' => '\yiiplus\websocket\<dirver>\WebSocket',
            'host' => '127.0.0.1',
            'port' => 9501,
            'channels' => [
                'push-message' => '\xxx\channels\PushMessageChannel', // 配置 channel 对应的执行类
            ],
      ],
    ],
    
    1 条回复
    回复于 2019-01-11 20:22 回复

    文章已修改

您需要登录后才可以回复。登录 | 立即注册