public function bind()
{
$err = $errno = 0;
$this->FLASH_POLICY_FILE = str_replace('to-ports="*', 'to-ports="' . $this->uri->getPort() ?: 80, $this->FLASH_POLICY_FILE);
$serverSocket = stream_socket_server($this->uri->toString(), $errno, $err, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $this->_context);
$this->_logger->notice(sprintf("phpws listening on %s", $this->uri->toString()));
if ($serverSocket == false) {
$this->_logger->err("Error: {$err}");
return;
}
$timeOut =& $this->purgeUserTimeOut;
$sockets = $this->_streams;
$that = $this;
$logger = $this->_logger;
$this->loop->addReadStream($serverSocket, function ($serverSocket) use($that, $logger, $sockets) {
try {
$newSocket = stream_socket_accept($serverSocket);
} catch (\ErrorException $e) {
$newSocket = false;
}
if (false === $newSocket) {
return;
}
stream_set_blocking($newSocket, 0);
$client = new WebSocketConnection($newSocket, $that->loop, $logger);
$sockets->attach($client);
$client->on("handshake", function (Handshake $request) use($that, $client) {
$that->emit("handshake", array($client->getTransport(), $request));
});
$client->on("connect", function () use($that, $client, $logger) {
$con = $client->getTransport();
$that->getConnections()->attach($con);
$that->emit("connect", array("client" => $con));
});
$client->on("message", function ($message) use($that, $client, $logger) {
$connection = $client->getTransport();
$that->emit("message", array("client" => $connection, "message" => $message));
});
$client->on("close", function () use($that, $client, $logger, &$sockets, $client) {
$sockets->detach($client);
$connection = $client->getTransport();
if ($connection) {
$that->getConnections()->detach($connection);
$that->emit("disconnect", array("client" => $connection));
}
});
$client->on("flashXmlRequest", function () use($that, $client) {
$client->getTransport()->sendString($that->FLASH_POLICY_FILE);
$client->close();
});
});
$this->loop->addPeriodicTimer(5, function () use($timeOut, $sockets, $that) {
# Lets send some pings
foreach ($that->getConnections() as $c) {
if ($c instanceof WebSocketTransportHybi) {
$c->sendFrame(WebSocketFrame::create(WebSocketOpcode::PingFrame));
}
}
$currentTime = time();
if ($timeOut == null) {
return;
}
foreach ($sockets as $s) {
if ($currentTime - $s->getLastChanged() > $timeOut) {
$s->close();
}
}
});
}
public function launch() { $server = new WebSocketServer($this->config['url'], $this->loop, $this->logger); $this->loop->addPeriodicTimer($this->config['delay_try_reconnect'], function () { $timer = 0; foreach ($this->bots_retrying as $tb_id => $true) { $this->loop->addTimer($timer++, function () use($tb_id) { $this->logger->debug('Try to reconnect client for bot ' . $tb_id); $this->addSlackClient($this->bots[$tb_id]); }); } }); $this->loop->addPeriodicTimer($this->config['delay_ping'], function () { foreach ($this->bots_connected as $tb_id => $connected) { if ($connected) { $always_connected = $this->bots[$tb_id]->clientSendPing(); if (!$always_connected) { $this->logger->warn('Ping fail set to retry for bot ' . $tb_id); $this->setToRetry($this->bots[$tb_id]); } } } }); $server->on('message', function (WebSocketTransportInterface $user, WebSocketMessage $message) { $data = json_decode($message->getData(), true); $this->logger->debug("Bot2hook websocket server receive message " . $message->getData()); if (is_array($data) && isset($data['type'])) { switch ($data['type']) { case 'add_bot': $this->logger->debug("New bot receive via incomming webhook " . json_encode($data['bot'])); $bot = new Bot($data['bot']); $this->addSlackClient($bot); break; case 'status': $user->sendString(json_encode(['bot2hook' => ['bots' => $this->bots, 'bots_connected' => $this->bots_connected, 'bots_retrying' => $this->bots_retrying]])); break; case 'reporting': $user->sendString(json_encode(['memory' => ['usage' => memory_get_usage(true), 'peak_usage' => memory_get_peak_usage(true), 'limit' => $this->getMemoryLimit()], 'bots_count' => ['connected' => count($this->bots_connected), 'retrying' => count($this->bots_retrying)]])); break; } } }); $server->bind(); $this->init(); $this->loop->run(); }