设置长度解析函数,支持C++或PHP的2种类型的函数。长度函数必须返回一个整数。
0
,数据不足,需要接收更多数据-1
,数据错误,底层会自动关闭连接默认底层最大会读取8K
的数据,如果包头的长度较小可能会存在内存复制的消耗。可设置package_body_offset
参数,底层只读取包头进行长度解析。
由于ZendVM
不支持运行在多线程环境,因此底层会自动使用Mutex
互斥锁对PHP
长度函数进行加锁,避免并发执行PHP
函数。在1.9.3
或更高版本可用。
请勿在长度解析函数中执行阻塞
IO
操作,可能导致所有Reactor
线程发生阻塞
$serv = new swoole_server("127.0.0.1", 9501);
$serv->set(array(
'open_length_check' => true,
'dispatch_mode' => 1,
'package_length_func' => function ($data) {
if (strlen($data) < 8) {
return 0;
}
$length = intval(trim(substr($data, 0, 8)));
if ($length <= 0) {
return -1;
}
return $length + 8;
},
'package_max_length' => 2000000, //协议最大长度
));
$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data)
{
var_dump($data);
echo "#{$serv->worker_id}>> received length=" . strlen($data) . "\n";
});
$serv->start();
在其他PHP扩展中,使用swoole_add_function
注册长度函数到Swoole
引擎中。
C++长度函数调用时底层不会加锁,需要调用方自行保证线程安全性
#include <string>
#include <iostream>
#include "swoole.h"
using namespace std;
int test_get_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t length);
void register_length_function(void)
{
swoole_add_function((char *) "test_get_length", (void *) test_get_length);
return SW_OK;
}
int test_get_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t length)
{
printf("cpp, size=%d\n", length);
return 100;
}