static PHP_METHOD(swoole_websocket_server, exist) { zval *zobject = getThis(); long fd; if (SwooleGS->start == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server is not running."); RETURN_FALSE; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) { return; } swServer *serv = swoole_get_object(zobject); swConnection *conn = swWorker_get_connection(serv, fd); if (!conn) { RETURN_FALSE; } //connection is closed if (conn->active == 0 || conn->closed) { RETURN_FALSE; } //have not handshake if (conn->websocket_status < WEBSOCKET_STATUS_ACTIVE) { RETURN_FALSE; } RETURN_TRUE; }
int swFactory_end(swFactory *factory, int fd) { swServer *serv = factory->ptr; swSendData _send; swDataHead info; bzero(&_send, sizeof(_send)); _send.info.fd = fd; _send.info.len = 0; _send.info.type = SW_EVENT_CLOSE; swConnection *conn = swWorker_get_connection(serv, fd); if (conn == NULL || conn->active == 0) { //swWarn("can not close. Connection[%d] not found.", _send.info.fd); return SW_ERR; } else if (conn->close_force) { goto do_close; } else if (conn->closing) { swWarn("The connection[%d] is closing.", fd); return SW_ERR; } else if (conn->closed) { return SW_ERR; } else { do_close: conn->closing = 1; if (serv->onClose != NULL) { info.fd = fd; info.from_id = conn->from_id; info.from_fd = conn->from_fd; serv->onClose(serv, &info); } conn->closing = 0; conn->closed = 1; conn->close_errno = 0; if (swBuffer_empty(conn->out_buffer)) { swReactor *reactor = &serv->reactor_threads[SwooleTG.id].reactor; return swReactorThread_close(reactor, conn->fd); } else { swBuffer_trunk *trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_CLOSE, 0); trunk->store.data.val1 = _send.info.type; return SW_OK; } } }
static int swFactoryProcess_end(swFactory *factory, int fd) { swServer *serv = factory->ptr; swSendData _send; swDataHead info; bzero(&_send, sizeof(_send)); _send.info.fd = fd; _send.info.len = 0; _send.info.type = SW_EVENT_CLOSE; swConnection *conn = swWorker_get_connection(serv, fd); if (conn == NULL || conn->active == 0) { SwooleG.error = SW_ERROR_SESSION_NOT_EXIST; return SW_ERR; } else if (conn->close_force) { goto do_close; } else if (conn->closing) { swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSING, "The connection[%d] is closing.", fd); return SW_ERR; } else if (conn->closed) { return SW_ERR; } else { do_close: conn->closing = 1; if (serv->onClose != NULL) { info.fd = fd; if (conn->close_actively) { info.from_id = -1; } else { info.from_id = conn->from_id; } info.from_fd = conn->from_fd; serv->onClose(serv, &info); } conn->closing = 0; conn->closed = 1; conn->close_errno = 0; return factory->finish(factory, &_send); } }
void swoole_websocket_onOpen(swoole_http_client *client) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int fd = client->fd; swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); if (!conn) { swWarn("connection[%d] is closed.", fd); return; } conn->websocket_status = WEBSOCKET_STATUS_HANDSHAKE; swTrace("\n\n\n\nconn ws status:%d, fd=%d\n\n\n", conn->websocket_status, fd); if (websocket_callbacks[WEBSOCKET_CALLBACK_onOpen]) { swTrace("\n\n\n\nhandshake success\n\n\n"); zval **args[2]; swServer *serv = SwooleG.serv; zval *zserv = (zval *) serv->ptr2; zval *zrequest_object = client->request.zrequest_object; zval *retval = NULL; #ifdef __CYGWIN__ //TODO: memory error on cygwin. sw_zval_add_ref(&zrequest_object); #endif args[0] = &zserv; args[1] = &zrequest_object; if (sw_call_user_function_ex(EG(function_table), NULL, websocket_callbacks[WEBSOCKET_CALLBACK_onOpen], &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "onOpen handler error"); } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } } }
int my_onReceive(swFactory *factory, swEventData *req) { int ret; char resp_data[SW_BUFFER_SIZE]; swServer *serv = factory->ptr; swSendData resp; g_receive_count++; memcpy(&resp.info, &req->info, sizeof(resp.info)); printf("recv %d bytes, data=%s\n", req->info.len, req->data); int n = snprintf(resp_data, SW_BUFFER_SIZE, "Server: %*s", req->info.len, req->data); resp_data[n] = '\0'; resp.data = resp_data; resp.info.len = n; resp.info.type = SW_EVENT_TCP; resp.length = 0; printf("send %d bytes. data=%s\n", n, resp_data); return SW_OK; ret = factory->finish(factory, &resp); if (ret < 0) { printf("send to client fail. errno=%d\n", errno); } if (req->info.from_id >= serv->reactor_num) { struct in_addr addr; addr.s_addr = req->info.fd; //printf("onReceive[%d]: ip=%s:%d, Data=%s\n", g_receive_count, inet_ntoa(addr), req->info.from_id, rtrim(req->data, req->info.len)); } else { swConnection *conn = swWorker_get_connection(serv, req->info.fd); swoole_rtrim(req->data, req->info.len); printf("onReceive[%d]: ip=%s|port=%d Data=%s|Len=%d\n", g_receive_count, swConnection_get_ip(conn), swConnection_get_port(conn), req->data, req->info.len); } // req->info.type = 99; // factory->event(factory, g_controller_id, req); return SW_OK; }
static PHP_METHOD(swoole_websocket_server, push) { zval *zdata; long fd = 0; long opcode = WEBSOCKET_OPCODE_TEXT_FRAME; zend_bool fin = 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|lb", &fd, &zdata, &opcode, &fin) == FAILURE) { return; } if (fd <= 0) { swoole_php_fatal_error(E_WARNING, "fd[%d] is invalid.", (int )fd); RETURN_FALSE; } if (opcode > WEBSOCKET_OPCODE_PONG) { swoole_php_fatal_error(E_WARNING, "opcode max 10"); RETURN_FALSE; } char *data; int length = php_swoole_get_send_data(zdata, &data TSRMLS_CC); if (length < 0) { RETURN_FALSE; } else if (length == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "data is empty."); RETURN_FALSE; } swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); if (!conn || conn->websocket_status < WEBSOCKET_STATUS_HANDSHAKE) { swoole_php_fatal_error(E_WARNING, "connection[%d] is not a websocket client.", (int ) fd); RETURN_FALSE; } swString_clear(swoole_http_buffer); swWebSocket_encode(swoole_http_buffer, data, length, opcode, (int) fin, 0); SW_CHECK_RETURN(swServer_tcp_send(SwooleG.serv, fd, swoole_http_buffer->str, swoole_http_buffer->length)); }
static int swFactoryProcess_end(swFactory *factory, int fd) { swServer *serv = factory->ptr; swSendData _send; swDataHead info; bzero(&_send, sizeof(_send)); _send.info.fd = fd; _send.info.len = 0; _send.info.type = SW_EVENT_CLOSE; swConnection *conn = swWorker_get_connection(serv, fd); if (conn == NULL || conn->active == 0) { //swWarn("can not close. Connection[%d] not found.", _send.info.fd); return SW_ERR; } else if (conn->close_force) { goto do_close; } else if (conn->closing) { swWarn("The connection[%d] is closing.", fd); return SW_ERR; } else if (conn->closed) { return SW_ERR; } else { do_close: conn->closing = 1; if (serv->onClose != NULL) { info.fd = fd; info.from_id = conn->from_id; info.from_fd = conn->from_fd; serv->onClose(serv, &info); } conn->closing = 0; conn->closed = 1; return factory->finish(factory, &_send); } }
void swoole_websocket_onOpen(http_context *ctx) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int fd = ctx->fd; swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); if (!conn) { swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "session[%d] is closed.", fd); return; } conn->websocket_status = WEBSOCKET_STATUS_ACTIVE; zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen); if (zcallback) { zval **args[2]; swServer *serv = SwooleG.serv; zval *zserv = (zval *) serv->ptr2; zval *zrequest_object = ctx->request.zobject; zval *retval = NULL; args[0] = &zserv; args[1] = &zrequest_object; if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "onOpen handler error"); } if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } } }
void swoole_websocket_onOpen(http_context *ctx) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif int fd = ctx->fd; swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); if (!conn) { swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "session[%d] is closed.", fd); return; } conn->websocket_status = WEBSOCKET_STATUS_ACTIVE; zend_fcall_info_cache *cache = php_swoole_server_get_cache(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen); if (cache) { swServer *serv = SwooleG.serv; zval *zserv = (zval *) serv->ptr2; zval *zrequest_object = ctx->request.zobject; zval *retval = NULL; #ifndef SW_COROUTINE zval **args[2]; args[0] = &zserv; args[1] = &zrequest_object; #else zval *args[2]; args[0] = zserv; args[1] = zrequest_object; #endif #ifndef SW_COROUTINE zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen); if (sw_call_user_function_fast(zcallback, cache, &retval, 2, args TSRMLS_CC) == FAILURE) { swoole_php_error(E_WARNING, "onOpen handler error"); } #else int ret = coro_create(cache, args, 2, &retval, NULL, NULL); if (ret != 0) { if (ret == CORO_LIMIT) { SwooleG.serv->factory.end(&SwooleG.serv->factory, fd); } return; } #endif if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); } if (retval) { sw_zval_ptr_dtor(&retval); } } }