× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

WebSocket\Server->push

WebSocket\Server->push1.7.11以上版本可用

websocket客户端连接推送数据,长度最大不得超过2M

function WebSocket\Server->push(int $fd, $data, int $opcode = 1, bool $finish = true);

参数模式1

  • $fd 客户端连接的ID,如果指定的$fd对应的TCP连接并非websocket客户端,将会发送失败
  • $data 要发送的数据内容
  • $opcode,指定发送数据内容的格式,默认为文本。发送二进制内容$opcode参数需要设置为WEBSOCKET_OPCODE_BINARY
  • 发送成功返回true,发送失败返回false

参数模式2

需要4.2.0及以上版本,若传入的$data是对象则其后续参数会被忽略

finish参数

自v4.4.12版本起,finish参数(bool型)改为flags(int型)以支持Websocket压缩,finish对应SWOOLE_WEBSOCKET_FLAG_FIN值为1,原有bool型值会隐式转换为int型,此改动向下兼容无影响。 此外压缩flag为SWOOLE_WEBSOCKET_FLAG_COMPRESS


  • 止水之约

    $binary 需要设为2,才是二进制

  • uiexp

    push所用客户端怎么办?循环?

  • moxiaobai

    foreach($server->connections as $fd) { $server->push($fd, json_encode($data)); }

  • Rango-韩天峰

    感谢反馈,已经修正。

  • lion

    push和send有啥区别啊。。。 搞不清楚应用场景

  • poboy

    为什么 count($server->connections)得到的条数,老是多了一条那??? push时会 有错误警告

  • laravela

    为什么 count($server->connections)得到的条数,老是多了一条那??? push时会 有错误警告

  • laravela

    不止多一条。有时候还会push不到正在连接的客户端

  • 张广运

    $server除了了push方法外还有其它方法吗

  • 111

    到底如何获取所有客户端id啊? 百度也查不到,只能存数据库吗?

  • 111

    没高人指点还得靠自己摸索。用swoole_table,每次连接把获取到的fd存到table里面,为了新手不走弯路我把代码贴一下吧,都是官方代码。

    $table = new swoole_table(1024);
    $table->column('fd', swoole_table::TYPE_INT);
    $table->create();
    
    $ws = new swoole_websocket_server("0.0.0.0", 9502);
    $ws->table = $table;;
    
    //监听WebSocket连接打开事件
    $ws->on('open', function ($ws, $request) {  
    
        $ws->table->set($request->fd, array('fd' => $request->fd));//获取客户端id插入table
    
            foreach ($ws->table as $u) {
                    var_dump($u); //输出整个table
            }           
    }); 
    
    //监听WebSocket消息事件
    $ws->on('message', function ($ws, $frame) {
        echo $frame->fd.":{$frame->data}";
    
            foreach ($ws->table as $u) {
                    $ws->push($u['fd'], $frame->data );//消息广播给所有客户端
            }       
    });
    
    //监听WebSocket连接关闭事件
    $ws->on('close', function ($ws, $fd) {
        echo "client-{$fd} is closed\n"; 
        $ws->table->del($fd);//从table中删除断开的id
    });
    $ws->start();
    

    把table想成一个数据库,第一列是主键fd,第二列是自己定义的数据,上面也定义的fd。

  • 111

    突然发现3楼的方法也是可以的....... 为什么这些官方文档都没有啊?真是坑死我了

  • 化身石桥千百年

    哈哈,解决了我的问题,多谢

  • 吕海峰

    点对点通讯应该怎样做?就像qq里边的单聊

  • 落月孤倚

    用redis 集合 每次连接进来 sadd 到集合里面,广播的时候 SMEMBERS取出来 循环推送.

  • 昌维

    send是websocket客户端的发数据方法

  • 王建民

    段错误 (核心已转储) 是怎么回事 我同时new tcp 和 webscoket 就出现这了

  • 许

    不同 worker_id 之间 如何push?

  • skating

    是文档没更新完整的吗?我看着测试代码里面好像有swoole_websocket_server->defer()这个方法

  • 大灰狼

    如果是16进制的该咋办啊

  • 聽見、、風聲

    我发现推送推送已经不存在(或已经断开)的fd返回的数据居然也是true

  • 包赢不输

    swoole_websocket_server::push(): the connected client of connection[437] is not a websocket client. 报这个致命错误是什么意思?

  • richard

    @聽見、、風聲 我也发现这个问题 这个暂时只能在客户端做业务应答了, push返回的状态在断开连接时候,也是返回true.

  • 简单的

    @包赢不输 问题解决了吗 我也碰见这个问题 chrome http请求的时候报的

  • 东阳居士

    @大灰狼 可以使用PHP pack函数包装一下

  • Xavier

    Swoole\WebSocket\Server::push(): the connected client of connection[518] is not a websocket client. 这个问题我也遇到了,请问是什么原因呢

  •  Tomskype

    Swoole\WebSocket\Server::push(): the connected client of connection[518] is not a websocket client. 这个问题我也遇到了,请问是什么原因呢

  • 盒子

    @Xavier @Tomskype socket服务要使用swoole_process多进程模式, swoole_base是不行的.

  • 旧城半夏

    $fd 客户端连接的ID。这个ID可以自己设置吗?如果要给客户端发送消息的话要一个自定义的ID

  • 国1家1宁

    Warning: Swoole\WebSocket\Server::push(): fd[0] is invalid. ???

  • 阿讷

    @国1家1宁 fd[0] 肯定不对,fid没有等于0的

  • 新用户(手机注册)

    客户端已经断开网络,此时push仍会返回true。请问下这个是正常的吗?

  • qq240944930

    发现一个问题 push发送的数据如果末尾没有\n 我连接的ssh面板就会出现乱码 各位别踩坑了

  • H̶

    Swoole\WebSocket\Server::push(): the connected client of connection[1] is no这是什么问题啊

  • H̶

    Swoole\WebSocket\Server::push(): the connected client of connection[1] is not a websocket client.大佬这个问题怎么解决啊

  • Jason

    0000

  • wc1217

    出现 Swoole\WebSocket\Server::push(): the connected client of connection[1] is not a websocket client or closed 是因为2秒tick一下的问题,tick的时候$fd已经关闭了。 只要set open_websocket_close_frame =>true 之后判断一下opcode===0x08就行

  • wc1217

    天坑: SWOOLE_BASE模式下不支持跨进程操作TCP连接,因此在BASE模式中,只能在当前进程内使用$connections迭代器。

  • 十四

    Swoole\WebSocket\Server::push(): the connected client of connection[1] is not a websocket client 在onRequest方法中for操作时,增加 if ($this->swoole->isEstablished($fd)) 这一步 判断 foreach ($this->swoole->connections as $fd) { if ($this->swoole->isEstablished($fd)) { $this->swoole->push($fd, 'test'); } }