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

Server->send

向客户端发送数据,函数原型:

bool Server->send(mixed $fd, string $data, int $serverSocket = -1);

发送过程是异步的,底层会自动监听可写,将数据逐步发送给客户端

参数

  • $fd,客户端的文件描述符
  • $data,发送的数据,TCP协议最大不得超过2M,可修改 buffer_output_size 改变允许发送的最大包长度
  • $serverSocket,向Unix Socket DGRAM对端发送数据时需要此项参数,TCP客户端不需要填写

返回值

  • 发送成功会返回true
  • 发送失败会返回false,调用$server->getLastError()方法可以得到失败的错误码

安全性

  • send操作具有原子性,多个进程同时调用send向同一个TCP连接发送数据,不会发生数据混杂

长度限制

  • 如果要发送超过2M的数据,可以将数据写入临时文件,然后通过sendfile接口进行发送
  • 通过设置 buffer_output_size 参数可以修改发送长度的限制
  • 在发送超过8K的数据时,底层会启用Worker进程的共享内存,需要进行一次Mutex->lock操作

缓存区

  • Worker进程的管道缓存区已满时,发送8K数据将启用临时文件存储
  • 如果连续向同一个客户端发送大量数据,可能会导致Socket内存缓存区塞满,底层会立即返回false,应用程序可以调整socket_buffer_size设置,或 将数据保存到磁盘,等待客户端收完已发送的数据后再进行发送

协程调度

在协程模式下send遇到缓存区已满时会自动挂起,当触发onBufferEmpty时恢复协程,继续发送数据。

UnixSocket

监听UnixSocket DGRAM端口时,可以使用send向对端发送数据。

$serv->on("packet", function (Swoole\Server $serv, $data, $addr)
{
    $serv->send($addr['address'], 'SUCCESS', $addr['server_socket']);
});

  • 啊啊

    $fd 从哪里能够获取到

  • 安达英司

    receive回调中,你看下面的事件列表。

  • swoole粉

    关于send这块,给客户端进行socket传输的时候。需要考虑丢包粘包等传输问题吗。

  • Pader

    1.7.5 在 FreeBSD 10 上,使用 send 发送字符串只要稍微有些长,就会发送失败,控制台输出:[2014-09-27 13:45:45] WARN swFactoryProcess_finish: sendto to reactor failed. Error: Message too long [40]

  • swoole使用者

    $serv->send($self_fd, $self_msg);
    $serv->send($other_fd, $other_msg); $self_msg,$other_msg 都是10kb左右的数据,发送的时候,客服端接收到的数据都是$other_msg呢?当我sleep(1);的时候就可以了,请问这是什么问题导致的呢?

  • 史高雄

    我以API的形式提供服务,用户请求的数据长度很可能会超过2M,如果以文件的形式发送,又会改变接口协议,不现实,这种情况该怎么处理呢?求指教

  • 史高雄

    以send和sendfile发送到客户端的内容,用户接受到的内容形式是一样的吗

  • 比尔

    send中的Data尝试发送bool或是位数小于6位的字符串和数字,浏览器通通得不到返回值。使用的是1.7.8-stable版本。data 长度大于等于6位即可,这是为什么?

  • 陈晓生

    为什么一调用sendfile进程就退出呢

  • 陈宇哲

    PHP Warning: swoole_server::send(): cannot send to client in task worker with SWOOLE_BASE mode. 我是使用 Cygwin 配置的

  • Su孤兒zzzzzzzJ

    我用send会提示 WARN swReactorProcess_send2client: send[0] failed, session#5 has expired.

  • 学习swoole

    怎么给所有人发送消息呢?

  • YY

    为什么我用send向客户端发消息,客户端只能接受到两次 $data = 123456; $serv->send( $fd, $data ); $serv->send( $fd, $data ); $serv->send( $fd, $data ); $serv->send( $fd, $data );

  • Clive

    我也发现这个问题,为什么$client->recv() 只能收到2次,我发了3次,2次以下都可以,3次及以上被阻塞了

  • YY

    有些发送的合到一条里面被接收的

  • Clive

    应该不是包合并的问题,我客户端配置了这3个以eof结尾的 'package_eof'=>DB_EOF, 'open_eof_split' => true, 'open_eof_check' => true,

  • 刘钢Gary

    send失败 $server->getLastError() 为0是什么情况

  • lauterrance

    在onTask里调用send(fd, 'xxxx')时候为什么发送成功后就会自动关闭fd?????