看聊天室的代码的时候有点疑惑:
// 创建一个 异步的tcp连接
// 请查看BusinessWorker::tryToConnectGateway方法
$gateway_connection = new AsyncTcpConnection("GatewayProtocol://$addr");
// 然后发送一些数据
// 请查看BusinessWorker::tryToConnectGateway方法
$gateway_connection->send($gateway_data);
$gateway_connection->connect();
}
由于AsyncTcpConnection的初始status状态都是connecting状态,所以send的时候都会先直接把buffer先存起来,然后直接return ,进入到connect方法,connect方法则stream_socket_client连接服务端,同时将连接成功后的socket放入全局监听中,等待Select::Loop, 。
问题就是:
此时对于这条连接来说,stream_select 什么时候才能监听到?且刚刚send中没有写入socket的数据是从哪里开始写进去的呢?
(新手,问题若太简单,请勿喷。)
下面是 AsyncTcpConnection::$connect的代码:
public function connect()
{
// Open socket connection asynchronously.
$this->_socket = stream_socket_client("tcp://{$this->_remoteAddress}", $errno, $errstr, 0,
STREAM_CLIENT_ASYNC_CONNECT);
// If failed attempt to emit onError callback.
if (!$this->_socket) {
$this->_status = self::STATUS_CLOSED;
$this->emitError(WORKERMAN_CONNECT_FAIL, $errstr);
return;
}
// Add socket to global event loop waiting connection is successfully established or faild.
Worker::$globalEvent->add($this->_socket, EventInterface::EV_WRITE, array($this, 'checkConnection'));
}
http://wenda.workerman.net/?/question/30
按帖里面说的话,当客户端连接建立成功之后返回的socket,加入到监听之后会被stream_select监听到可写,之后就按绑定的handler去处理就能够将数据发送出去了,恩,应该是这样子。
是的。
当发起异步链接后会立刻返回socket句柄,这时候系统底层异步去tcp三次握手,workerman把这个socket句柄加入到stream_select/epoll监听,当socket句柄可写时去判断检查socket是否连上,(socket可写有两种可能,1、tcp连上了 2、tcp没连上),如果连上了就判断下是否有未发送的数据,有的话就发送。