《就是要你懂Swoole》—使用Swoole\Client的时候需要注意的地方

今早看Swoole修复了一个创建Swoole\Client的bug,我记得之前是没有的,应该是用C++重构Swoole的时候出现的。Issue在这里#2568,修复在这里 [e9fb220]。

原来的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
if (cli->async)
{
client_callback *cb = (client_callback *) swoole_get_property(getThis(), 0);
if (!cb)
{
swoole_php_fatal_error(E_ERROR, "no event callback function");
RETURN_FALSE;
}

if (swSocket_is_stream(cli->type))
{
if (!cb->cache_onConnect.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onConnect' callback function");
RETURN_FALSE;
}
if (!cb->cache_onError.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onError' callback function");
RETURN_FALSE;
}
if (!cb->cache_onClose.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onClose' callback function");
RETURN_FALSE;
}
cli->onConnect = client_onConnect;
cli->onClose = client_onClose;
cli->onError = client_onError;
cli->onReceive = client_onReceive;
cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT;
if (cb->cache_onBufferFull.function_handler)
{
cli->onBufferFull = client_onBufferFull;
}
if (cb->cache_onBufferEmpty.function_handler)
{
cli->onBufferEmpty = client_onBufferEmpty;
}
}
else
{
if (!cb || !cb->cache_onReceive.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onReceive' callback function");
RETURN_FALSE;
}
if (cb->cache_onConnect.function_handler)
{
cli->onConnect = client_onConnect;
}
if (cb->cache_onClose.function_handler)
{
cli->onClose = client_onClose;
}
if (cb->cache_onError.function_handler)
{
cli->onError = client_onError;
}
cli->onReceive = client_onReceive;
cli->reactor_fdtype = PHP_SWOOLE_FD_DGRAM_CLIENT;
}

zval *zobject = getThis();
cli->object = zobject;
sw_copy_to_stack(cli->object, cb->_object);
Z_TRY_ADDREF_P(zobject);
}

现在代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
if (cli->async)
{
client_callback *cb = (client_callback *) swoole_get_property(getThis(), 0);
if (!cb)
{
swoole_php_fatal_error(E_ERROR, "no event callback function");
RETURN_FALSE;
}
if (!cb->cache_onReceive.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onReceive' callback function");
RETURN_FALSE;
}
if (swSocket_is_stream(cli->type))
{
if (!cb->cache_onConnect.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onConnect' callback function");
RETURN_FALSE;
}
if (!cb->cache_onError.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onError' callback function");
RETURN_FALSE;
}
if (!cb->cache_onClose.function_handler)
{
swoole_php_fatal_error(E_ERROR, "no 'onClose' callback function");
RETURN_FALSE;
}
cli->onConnect = client_onConnect;
cli->onClose = client_onClose;
cli->onError = client_onError;
cli->onReceive = client_onReceive;
cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT;
if (cb->cache_onBufferFull.function_handler)
{
cli->onBufferFull = client_onBufferFull;
}
if (cb->cache_onBufferEmpty.function_handler)
{
cli->onBufferEmpty = client_onBufferEmpty;
}
}
else
{
if (cb->cache_onConnect.function_handler)
{
cli->onConnect = client_onConnect;
}
if (cb->cache_onClose.function_handler)
{
cli->onClose = client_onClose;
}
if (cb->cache_onError.function_handler)
{
cli->onError = client_onError;
}
cli->onReceive = client_onReceive;
cli->reactor_fdtype = PHP_SWOOLE_FD_DGRAM_CLIENT;
}

zval *zobject = getThis();
cli->object = zobject;
sw_copy_to_stack(cli->object, cb->_object);
Z_TRY_ADDREF_P(zobject);
}

之前是如果socket不是stream类型的时候才会判断是否定义了onReceive回调函数。现在把对是否定义了onReceive的判断放在了

1
if (swSocket_is_stream(cli->type))

的上面,因此就变成了无论是不是stream类型的,都需要定义onReceive回调函数。

另外,Swoole创建的Client如果是Stream类型的,那么必须实现onConnectonReceiveonErroronClose回调函数函数。如果不是Stream类型的,则可以不实现。当然,实现了这些回调函数也是可以的。从最近的一次修复来看。必须实现onReceive回调函数。(以上是在调用client->connect的时候进行判断的)