public function open($timeOut = null)
{
/**
* @var $that self
*/
$that = new FullAccessWrapper($this);
$uri = new Uri($this->url);
$isSecured = 'wss' === $uri->getScheme();
$defaultPort = $isSecured ? 443 : 80;
$connector = new Connector($this->loop, $this->dns, $this->streamOptions);
if ($isSecured) {
$connector = new \React\SocketClient\SecureConnector($connector, $this->loop);
}
$deferred = new Deferred();
$connector->create($uri->getHost(), $uri->getPort() ?: $defaultPort)->then(function (\React\Stream\DuplexStreamInterface $stream) use($that, $uri, $deferred, $timeOut) {
if ($timeOut) {
$timeOutTimer = $that->loop->addTimer($timeOut, function () use($deferred, $stream, $that) {
$stream->close();
$that->logger->notice("Timeout occured, closing connection");
$that->emit("error");
$deferred->reject("Timeout occured");
});
} else {
$timeOutTimer = null;
}
$transport = new WebSocketTransportHybi($stream);
$transport->setLogger($that->logger);
$that->transport = $transport;
$that->stream = $stream;
$stream->on("close", function () use($that) {
$that->isClosing = false;
$that->state = WebSocket::STATE_CLOSED;
$that->emit('close');
});
// Give the chance to change request
$transport->on("request", function (Request $handshake) use($that) {
$that->emit("request", func_get_args());
});
$transport->on("handshake", function (Handshake $handshake) use($that) {
$that->request = $handshake->getRequest();
$that->response = $handshake->getRequest();
$that->emit("handshake", array($handshake));
});
$transport->on("connect", function () use(&$state, $that, $transport, $timeOutTimer, $deferred) {
if ($timeOutTimer) {
$timeOutTimer->cancel();
}
$deferred->resolve($transport);
$that->state = WebSocket::STATE_CONNECTED;
$that->emit("connect");
});
$transport->on('message', function ($message) use($that, $transport) {
$that->emit("message", array("message" => $message));
});
$transport->initiateHandshake($uri);
$that->state = WebSocket::STATE_HANDSHAKE_SENT;
}, function ($reason) use($that, $deferred) {
$deferred->reject($reason);
$that->logger->err($reason);
});
return $deferred->promise();
}