Metrics
0
Watch 281 Star 1.1K Fork 251

GVPswoole / swoole-srcCApache-2.0

Sign up for free
Explore and code with more than 2 million developers,Free private repositories !:)
Sign up
PHP的异步、并行、高性能网络通信引擎 spread retract

http://www.swoole.com/

  • C++ 38.3%
  • PHP 35.8%
  • C 24.8%
  • M4 0.5%
  • Shell 0.2%
  • Other 0.4%
Clone or download
swoole_server_port.cc 25.13 KB
Copy Edit Web IDE Raw Blame History
twosee authored 2019-06-14 14:29 . Add sw_ namespace
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#include "php_swoole_cxx.h"
using namespace std;
using namespace swoole;
zend_class_entry *swoole_server_port_ce;
static zend_object_handlers swoole_server_port_handlers;
struct server_port_event {
enum php_swoole_server_port_callback_type type;
std::string name;
server_port_event(enum php_swoole_server_port_callback_type type, std::string &&name) : type(type) , name(name) { }
};
static unordered_map<string, server_port_event> server_port_event_map({
{ "connect", server_port_event(SW_SERVER_CB_onConnect, "Connect") },
{ "receive", server_port_event(SW_SERVER_CB_onReceive, "Receive") },
{ "close", server_port_event(SW_SERVER_CB_onClose, "Close") },
{ "packet", server_port_event(SW_SERVER_CB_onPacket, "Packet") },
{ "bufferfull", server_port_event(SW_SERVER_CB_onBufferFull, "BufferFull") },
{ "bufferempty", server_port_event(SW_SERVER_CB_onBufferEmpty, "BufferEmpty") },
{ "request", server_port_event(SW_SERVER_CB_onRequest, "Request") },
{ "handshake", server_port_event(SW_SERVER_CB_onHandShake, "Handshake") },
{ "open", server_port_event(SW_SERVER_CB_onOpen, "Open") },
{ "message", server_port_event(SW_SERVER_CB_onMessage, "Message") },
});
static PHP_METHOD(swoole_server_port, __construct);
static PHP_METHOD(swoole_server_port, __destruct);
static PHP_METHOD(swoole_server_port, on);
static PHP_METHOD(swoole_server_port, set);
static PHP_METHOD(swoole_server_port, getCallback);
#ifdef SWOOLE_SOCKETS_SUPPORT
static PHP_METHOD(swoole_server_port, getSocket);
#endif
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_port_set, 0, 0, 1)
ZEND_ARG_ARRAY_INFO(0, settings, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_port_on, 0, 0, 2)
ZEND_ARG_INFO(0, event_name)
ZEND_ARG_CALLABLE_INFO(0, callback, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_port_getCallback, 0, 0, 1)
ZEND_ARG_INFO(0, event_name)
ZEND_END_ARG_INFO()
const zend_function_entry swoole_server_port_methods[] =
{
PHP_ME(swoole_server_port, __construct, arginfo_swoole_void, ZEND_ACC_PRIVATE)
PHP_ME(swoole_server_port, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC)
PHP_ME(swoole_server_port, set, arginfo_swoole_server_port_set, ZEND_ACC_PUBLIC)
PHP_ME(swoole_server_port, on, arginfo_swoole_server_port_on, ZEND_ACC_PUBLIC)
PHP_ME(swoole_server_port, getCallback, arginfo_swoole_server_port_getCallback, ZEND_ACC_PUBLIC)
#ifdef SWOOLE_SOCKETS_SUPPORT
PHP_ME(swoole_server_port, getSocket, arginfo_swoole_void, ZEND_ACC_PUBLIC)
#endif
PHP_FE_END
};
void swoole_server_port_init(int module_number)
{
SW_INIT_CLASS_ENTRY(swoole_server_port, "Swoole\\Server\\Port", "swoole_server_port", NULL, swoole_server_port_methods);
SW_SET_CLASS_SERIALIZABLE(swoole_server_port, zend_class_serialize_deny, zend_class_unserialize_deny);
SW_SET_CLASS_CLONEABLE(swoole_server_port, sw_zend_class_clone_deny);
SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_server_port, sw_zend_class_unset_property_deny);
SW_SET_CLASS_CREATE_WITH_ITS_OWN_HANDLERS(swoole_server_port);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onConnect"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onReceive"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onClose"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onPacket"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onBufferFull"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onBufferEmpty"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onRequest"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onHandShake"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onOpen"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("onMessage"), ZEND_ACC_PRIVATE);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("host"), ZEND_ACC_PUBLIC);
zend_declare_property_long(swoole_server_port_ce, ZEND_STRL("port"), 0, ZEND_ACC_PUBLIC);
zend_declare_property_long(swoole_server_port_ce, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC);
zend_declare_property_long(swoole_server_port_ce, ZEND_STRL("sock"), -1, ZEND_ACC_PUBLIC);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("setting"), ZEND_ACC_PUBLIC);
zend_declare_property_null(swoole_server_port_ce, ZEND_STRL("connections"), ZEND_ACC_PUBLIC);
}
/**
* [Master-Process]
*/
static ssize_t php_swoole_server_length_func(swProtocol *protocol, swConnection *conn, char *data, uint32_t length)
{
swServer *serv = (swServer *) protocol->private_data_2;
swServer_lock(serv);
zend_fcall_info_cache *fci_cache = (zend_fcall_info_cache *) protocol->private_data;
zval zdata;
zval retval;
ssize_t ret = -1;
// TODO: reduce memory copy
ZVAL_STRINGL(&zdata, data, length);
if (UNEXPECTED(sw_zend_call_function_ex(NULL, fci_cache, 1, &zdata, &retval) != SUCCESS))
{
php_swoole_fatal_error(E_WARNING, "length function handler error");
}
else
{
ret = zval_get_long(&retval);
zval_ptr_dtor(&retval);
}
zval_ptr_dtor(&zdata);
swServer_unlock(serv);
/* the exception should only be thrown after unlocked */
if (UNEXPECTED(EG(exception)))
{
zend_exception_error(EG(exception), E_ERROR);
}
return ret;
}
static PHP_METHOD(swoole_server_port, __construct)
{
php_swoole_fatal_error(E_ERROR, "please use the Swoole\\Server->listen method");
return;
}
static PHP_METHOD(swoole_server_port, __destruct)
{
SW_PREVENT_USER_DESTRUCT();
swoole_server_port_property *property = (swoole_server_port_property *) swoole_get_property(getThis(), 0);
swListenPort *port = property->port;
for (int j = 0; j < PHP_SWOOLE_SERVER_PORT_CALLBACK_NUM; j++)
{
if (property->caches[j])
{
efree(property->caches[j]);
property->caches[j] = NULL;
}
}
if (port->protocol.private_data)
{
sw_zend_fci_cache_discard((zend_fcall_info_cache *) port->protocol.private_data);
efree(port->protocol.private_data);
port->protocol.private_data = nullptr;
}
efree(property);
swoole_set_property(getThis(), 0, NULL);
swoole_set_object(getThis(), NULL);
}
static PHP_METHOD(swoole_server_port, set)
{
zval *zset = NULL;
HashTable *vht;
zval *ztmp;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY(zset)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
vht = Z_ARRVAL_P(zset);
swListenPort *port = (swListenPort *) swoole_get_object(getThis());
swoole_server_port_property *property = (swoole_server_port_property *) swoole_get_property(getThis(), 0);
if (port == NULL || property == NULL)
{
php_swoole_fatal_error(E_ERROR, "please use the swoole_server->listen method");
return;
}
//backlog
if (php_swoole_array_get_value(vht, "backlog", ztmp))
{
port->backlog = (int) zval_get_long(ztmp);
}
if (php_swoole_array_get_value(vht, "socket_buffer_size", ztmp))
{
port->socket_buffer_size = (int) zval_get_long(ztmp);
if (port->socket_buffer_size <= 0)
{
port->socket_buffer_size = INT_MAX;
}
}
/**
* !!! Don't set this option, for tests only.
*/
if (php_swoole_array_get_value(vht, "kernel_socket_recv_buffer_size", ztmp))
{
port->kernel_socket_recv_buffer_size = (int) zval_get_long(ztmp);
if (port->kernel_socket_recv_buffer_size <= 0)
{
port->kernel_socket_recv_buffer_size = INT_MAX;
}
}
/**
* !!! Don't set this option, for tests only.
*/
if (php_swoole_array_get_value(vht, "kernel_socket_send_buffer_size", ztmp))
{
port->kernel_socket_send_buffer_size = (int) zval_get_long(ztmp);
if (port->kernel_socket_send_buffer_size <= 0)
{
port->kernel_socket_send_buffer_size = INT_MAX;
}
}
if (php_swoole_array_get_value(vht, "buffer_high_watermark", ztmp))
{
port->buffer_high_watermark = (int) zval_get_long(ztmp);
}
if (php_swoole_array_get_value(vht, "buffer_low_watermark", ztmp))
{
port->buffer_low_watermark = (int) zval_get_long(ztmp);
}
//server: tcp_nodelay
if (php_swoole_array_get_value(vht, "open_tcp_nodelay", ztmp))
{
port->open_tcp_nodelay = zval_is_true(ztmp);
}
else
{
port->open_tcp_nodelay = 1;
}
//tcp_defer_accept
if (php_swoole_array_get_value(vht, "tcp_defer_accept", ztmp))
{
port->tcp_defer_accept = (uint8_t) zval_get_long(ztmp);
}
//tcp_keepalive
if (php_swoole_array_get_value(vht, "open_tcp_keepalive", ztmp))
{
port->open_tcp_keepalive = zval_is_true(ztmp);
}
//buffer: eof check
if (php_swoole_array_get_value(vht, "open_eof_check", ztmp))
{
port->open_eof_check = zval_is_true(ztmp);
}
//buffer: split package with eof
if (php_swoole_array_get_value(vht, "open_eof_split", ztmp))
{
port->protocol.split_by_eof = zval_is_true(ztmp);
if (port->protocol.split_by_eof)
{
port->open_eof_check = 1;
}
}
//package eof
if (php_swoole_array_get_value(vht, "package_eof", ztmp))
{
zend::string str_v(ztmp);
port->protocol.package_eof_len = str_v.len();
if (port->protocol.package_eof_len == 0)
{
php_swoole_fatal_error(E_ERROR, "pacakge_eof cannot be an empty string");
RETURN_FALSE;
}
else if (port->protocol.package_eof_len > SW_DATA_EOF_MAXLEN)
{
php_swoole_fatal_error(E_ERROR, "pacakge_eof max length is %d", SW_DATA_EOF_MAXLEN);
RETURN_FALSE;
}
bzero(port->protocol.package_eof, SW_DATA_EOF_MAXLEN);
memcpy(port->protocol.package_eof, str_v.val(), str_v.len());
}
//http_protocol
if (php_swoole_array_get_value(vht, "open_http_protocol", ztmp))
{
port->open_http_protocol = zval_is_true(ztmp);
}
//websocket protocol
if (php_swoole_array_get_value(vht, "open_websocket_protocol", ztmp))
{
port->open_websocket_protocol = zval_is_true(ztmp);
if (port->open_websocket_protocol)
{
port->open_http_protocol = 1;
}
}
if (php_swoole_array_get_value(vht, "websocket_subprotocol", ztmp))
{
zend::string str_v(ztmp);
if (port->websocket_subprotocol)
{
sw_free(port->websocket_subprotocol);
}
port->websocket_subprotocol = str_v.dup();
port->websocket_subprotocol_length = str_v.len();
}
if (php_swoole_array_get_value(vht, "open_websocket_close_frame", ztmp))
{
port->open_websocket_close_frame = zval_is_true(ztmp);
}
#ifdef SW_USE_HTTP2
//http2 protocol
if (php_swoole_array_get_value(vht, "open_http2_protocol", ztmp))
{
port->open_http2_protocol = zval_is_true(ztmp);
if (port->open_http2_protocol)
{
port->open_http_protocol = 1;
}
}
#endif
//buffer: mqtt protocol
if (php_swoole_array_get_value(vht, "open_mqtt_protocol", ztmp))
{
port->open_mqtt_protocol = zval_is_true(ztmp);
}
//redis protocol
if (php_swoole_array_get_value(vht, "open_redis_protocol", ztmp))
{
port->open_redis_protocol = zval_get_long(ztmp);
}
//tcp_keepidle
if (php_swoole_array_get_value(vht, "tcp_keepidle", ztmp))
{
port->tcp_keepidle = (uint16_t) zval_get_long(ztmp);
}
//tcp_keepinterval
if (php_swoole_array_get_value(vht, "tcp_keepinterval", ztmp))
{
port->tcp_keepinterval = (uint16_t) zval_get_long(ztmp);
}
//tcp_keepcount
if (php_swoole_array_get_value(vht, "tcp_keepcount", ztmp))
{
port->tcp_keepcount = (uint16_t) zval_get_long(ztmp);
}
//tcp_fastopen
if (php_swoole_array_get_value(vht, "tcp_fastopen", ztmp))
{
port->tcp_fastopen = zval_is_true(ztmp);
}
//open length check
if (php_swoole_array_get_value(vht, "open_length_check", ztmp))
{
port->open_length_check = zval_is_true(ztmp);
}
//package length size
if (php_swoole_array_get_value(vht, "package_length_type", ztmp))
{
zend::string str_v(ztmp);
port->protocol.package_length_type = str_v.val()[0];
port->protocol.package_length_size = swoole_type_size(port->protocol.package_length_type);
if (port->protocol.package_length_size == 0)
{
php_swoole_fatal_error(E_ERROR, "unknow package_length_type, see pack(). Link: http://php.net/pack");
RETURN_FALSE;
}
}
//package length offset
if (php_swoole_array_get_value(vht, "package_length_offset", ztmp))
{
port->protocol.package_length_offset = (int) zval_get_long(ztmp);
if (port->protocol.package_length_offset > SW_IPC_BUFFER_SIZE)
{
php_swoole_fatal_error(E_ERROR, "'package_length_offset' value is too large");
}
}
//package body start
if (php_swoole_array_get_value(vht, "package_body_offset", ztmp) || php_swoole_array_get_value(vht, "package_body_start", ztmp))
{
port->protocol.package_body_offset = (int) zval_get_long(ztmp);
if (port->protocol.package_body_offset > SW_IPC_BUFFER_SIZE)
{
php_swoole_fatal_error(E_ERROR, "'package_body_offset' value is too large");
}
}
//length function
if (php_swoole_array_get_value(vht, "package_length_func", ztmp))
{
while(1)
{
if (Z_TYPE_P(ztmp) == IS_STRING)
{
swProtocol_length_function func = (swProtocol_length_function) swoole_get_function(Z_STRVAL_P(ztmp), Z_STRLEN_P(ztmp));
if (func != NULL)
{
port->protocol.get_package_length = func;
break;
}
}
#ifdef ZTS
swServer *serv = property->serv;
if (serv->factory_mode == SW_MODE_PROCESS && !serv->single_thread)
{
php_swoole_fatal_error(E_ERROR, "option [package_length_func] does not support with ZTS");
}
#endif
char *func_name;
zend_fcall_info_cache *fci_cache = (zend_fcall_info_cache *) ecalloc(1, sizeof(zend_fcall_info_cache));
if (!sw_zend_is_callable_ex(ztmp, NULL, 0, &func_name, NULL, fci_cache, NULL))
{
php_swoole_fatal_error(E_ERROR, "function '%s' is not callable", func_name);
return;
}
efree(func_name);
port->protocol.get_package_length = php_swoole_server_length_func;
if (port->protocol.private_data)
{
sw_zend_fci_cache_discard((zend_fcall_info_cache *) port->protocol.private_data);
efree(port->protocol.private_data);
}
sw_zend_fci_cache_persist(fci_cache);
port->protocol.private_data = fci_cache;
break;
}
port->protocol.package_length_size = 0;
port->protocol.package_length_type = '\0';
port->protocol.package_length_offset = SW_IPC_BUFFER_SIZE;
}
/**
* package max length
*/
if (php_swoole_array_get_value(vht, "package_max_length", ztmp))
{
port->protocol.package_max_length = (int) zval_get_long(ztmp);
}
#ifdef SW_USE_OPENSSL
if (port->ssl)
{
if (php_swoole_array_get_value(vht, "ssl_cert_file", ztmp))
{
zend::string str_v(ztmp);
if (access(str_v.val(), R_OK) < 0)
{
php_swoole_fatal_error(E_ERROR, "ssl cert file[%s] not found", str_v.val());
return;
}
if (port->ssl_option.cert_file)
{
sw_free(port->ssl_option.cert_file);
}
port->ssl_option.cert_file = str_v.dup();
port->open_ssl_encrypt = 1;
}
if (php_swoole_array_get_value(vht, "ssl_key_file", ztmp))
{
zend::string str_v(ztmp);
if (access(str_v.val(), R_OK) < 0)
{
php_swoole_fatal_error(E_ERROR, "ssl key file[%s] not found", str_v.val());
return;
}
if (port->ssl_option.key_file)
{
sw_free(port->ssl_option.key_file);
}
port->ssl_option.key_file = str_v.dup();
}
if (php_swoole_array_get_value(vht, "ssl_method", ztmp))
{
port->ssl_option.method = (int) zval_get_long(ztmp);
}
if (php_swoole_array_get_value(vht, "ssl_verify_peer", ztmp))
{
port->ssl_option.verify_peer = zval_is_true(ztmp);
}
if (php_swoole_array_get_value(vht, "ssl_allow_self_signed", ztmp))
{
port->ssl_option.allow_self_signed = zval_is_true(ztmp);
}
//verify client cert
if (php_swoole_array_get_value(vht, "ssl_client_cert_file", ztmp))
{
zend::string str_v(ztmp);
if (access(str_v.val(), R_OK) < 0)
{
php_swoole_fatal_error(E_ERROR, "ssl_client_cert_file[%s] not found", str_v.val());
return;
}
if (port->ssl_option.client_cert_file)
{
sw_free(port->ssl_option.client_cert_file);
}
port->ssl_option.client_cert_file = str_v.dup();
}
if (php_swoole_array_get_value(vht, "ssl_verify_depth", ztmp))
{
port->ssl_option.verify_depth = (int) zval_get_long(ztmp);
}
if (php_swoole_array_get_value(vht, "ssl_prefer_server_ciphers", ztmp))
{
port->ssl_config.prefer_server_ciphers = zval_is_true(ztmp);
}
// if ((v = zend_hash_str_find(vht, ZEND_STRL("ssl_session_tickets"))))
// {
// port->ssl_config.session_tickets = zval_is_true(v);
// }
// if ((v = zend_hash_str_find(vht, ZEND_STRL("ssl_stapling"))))
// {
// port->ssl_config.stapling = zval_is_true(v);
// }
// if ((v = zend_hash_str_find(vht, ZEND_STRL("ssl_stapling_verify"))))
// {
// port->ssl_config.stapling_verify = zval_is_true(v);
// }
if (php_swoole_array_get_value(vht, "ssl_ciphers", ztmp))
{
if (port->ssl_config.ciphers)
{
sw_free(port->ssl_config.ciphers);
}
port->ssl_config.ciphers = zend::string(ztmp).dup();
}
if (php_swoole_array_get_value(vht, "ssl_ecdh_curve", ztmp))
{
if (port->ssl_config.ecdh_curve)
{
sw_free(port->ssl_config.ecdh_curve);
}
port->ssl_config.ecdh_curve = zend::string(ztmp).dup();
}
if (php_swoole_array_get_value(vht, "ssl_dhparam", ztmp))
{
if (port->ssl_config.dhparam)
{
sw_free(port->ssl_config.dhparam);
}
port->ssl_config.dhparam = zend::string(ztmp).dup();
}
// if ((v = zend_hash_str_find(vht, ZEND_STRL("ssl_session_cache"))))
// {
// port->ssl_config.session_cache = zend::string_dup(v);
// }
if (swPort_enable_ssl_encrypt(port) < 0)
{
php_swoole_fatal_error(E_ERROR, "swPort_enable_ssl_encrypt() failed");
RETURN_FALSE;
}
}
#endif
zval *zsetting = sw_zend_read_and_convert_property_array(swoole_server_port_ce, getThis(), ZEND_STRL("setting"), 0);
php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset));
property->zsetting = zsetting;
}
static PHP_METHOD(swoole_server_port, on)
{
char *name = NULL;
size_t len, i;
zval *cb;
swoole_server_port_property *property = (swoole_server_port_property *) swoole_get_property(getThis(), 0);
swServer *serv = property->serv;
if (serv->gs->start > 0)
{
php_swoole_fatal_error(E_WARNING, "can't register event callback function after server started");
RETURN_FALSE;
}
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &name, &len, &cb) == FAILURE)
{
RETURN_FALSE;
}
char *func_name = NULL;
zend_fcall_info_cache *fci_cache = (zend_fcall_info_cache *) emalloc(sizeof(zend_fcall_info_cache));
if (!sw_zend_is_callable_ex(cb, NULL, 0, &func_name, NULL, fci_cache, NULL))
{
php_swoole_fatal_error(E_ERROR, "function '%s' is not callable", func_name);
return;
}
efree(func_name);
const char *callback_name[PHP_SWOOLE_SERVER_PORT_CALLBACK_NUM] = {
"Connect",
"Receive",
"Close",
"Packet",
"Request",
"HandShake",
"Open",
"Message",
"BufferFull",
"BufferEmpty",
};
char property_name[128];
int l_property_name = 0;
memcpy(property_name, "on", 2);
for (i = 0; i < PHP_SWOOLE_SERVER_PORT_CALLBACK_NUM; i++)
{
if (strncasecmp(callback_name[i], name, len) != 0)
{
continue;
}
memcpy(property_name + 2, callback_name[i], len);
l_property_name = len + 2;
property_name[l_property_name] = '\0';
zend_update_property(swoole_server_port_ce, getThis(), property_name, l_property_name, cb);
property->callbacks[i] = sw_zend_read_property(swoole_server_port_ce, getThis(), property_name, l_property_name, 0);
sw_copy_to_stack(property->callbacks[i], property->_callbacks[i]);
if (property->caches[i])
{
efree(property->caches[i]);
}
property->caches[i] = fci_cache;
if (i == SW_SERVER_CB_onConnect && !serv->onConnect)
{
serv->onConnect = php_swoole_onConnect;
}
else if (i == SW_SERVER_CB_onPacket && !serv->onPacket)
{
serv->onPacket = php_swoole_onPacket;
}
else if (i == SW_SERVER_CB_onClose && !serv->onClose)
{
serv->onClose = php_swoole_onClose;
}
else if (i == SW_SERVER_CB_onBufferFull && !serv->onBufferFull)
{
serv->onBufferFull = php_swoole_onBufferFull;
}
else if (i == SW_SERVER_CB_onBufferEmpty && !serv->onBufferEmpty)
{
serv->onBufferEmpty = php_swoole_onBufferEmpty;
}
else if (i == SW_SERVER_CB_onMessage || i == SW_SERVER_CB_onRequest)
{
serv->onReceive = php_swoole_http_onReceive;
}
break;
}
if (l_property_name == 0)
{
php_swoole_error(E_WARNING, "unknown event types[%s]", name);
efree(fci_cache);
RETURN_FALSE;
}
RETURN_TRUE;
}
static PHP_METHOD(swoole_server_port, getCallback)
{
zval *name;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(name)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
zend::string _event_name_ori(name);
zend::string _event_name_tolower(zend_string_tolower(_event_name_ori.get()));
auto i = server_port_event_map.find(_event_name_tolower.to_std_string());
if (i != server_port_event_map.end())
{
string property_name = "on" + i->second.name;
zval rv, *property = zend_read_property(swoole_server_port_ce, getThis(), property_name.c_str(), property_name.length(), 1, &rv);
if (!ZVAL_IS_NULL(property))
{
RETURN_ZVAL(property, 1, 0);
}
}
RETURN_NULL();
}
#ifdef SWOOLE_SOCKETS_SUPPORT
static PHP_METHOD(swoole_server_port, getSocket)
{
swListenPort *port = (swListenPort *) swoole_get_object(getThis());
php_socket *socket_object = swoole_convert_to_socket(port->sock);
if (!socket_object)
{
RETURN_FALSE;
}
SW_ZEND_REGISTER_RESOURCE(return_value, (void *) socket_object, php_sockets_le_socket());
zval *zsocket = sw_zval_dup(return_value);
Z_TRY_ADDREF_P(zsocket);
}
#endif

Comment ( 0 )

You need to Sign in for post a comment

Help Search

Gitee_you_jiang_zheng_wen Zheng_wen_close