• Модуль: xmpp
  • Путь к файлу: ~/bitrix/modules/xmpp/classes/server.php
  • Класс: CXMPPServer
  • Вызов: CXMPPServer::Listen
protected function Listen()
{
	$this->__ReportKernel();
	$this->startClearPeriodTime = time();

	if (!$this->sockServer && !$this->sockServerSSL)
		return;

	COption::SetOptionInt('xmpp', 'LastActivityDate', time());

	while (true)
	{
		$arReadSockets = $this->arSockets;

		$w = null;
		$e = null;

		foreach ($arReadSockets as $k => $r)
		{
			if (get_resource_type($r) !== 'stream')
			{
				unset($arReadSockets[$k]);
			}
		}

		if (count($arReadSockets) > 0)
		{
			$n = stream_select($arReadSockets, $w, $e, 3);
			if ($n !== false && $n > 0)
			{
				foreach ($arReadSockets as $k => $r)
				{
					if ($this->sockServer && ($r == $this->sockServer))
					{
						if (is_resource($sock = stream_socket_accept($this->sockServer, 0, $ip)))
						{
							$this->lastClientId++;
							$id = $this->lastClientId;

							stream_set_timeout($sock, 5);
							$this->arClients[$id] = new CXMPPClient($id, $sock);
							$this->arSockets[$id + $this->socketsClientsStartIndex] = $sock;

							$this->WriteToLog("Client connected (".$id.")", 5);
						}
					}
					elseif ($this->sockServerSSL && ($r == $this->sockServerSSL))
					{
						if (is_resource($sock = stream_socket_accept($this->sockServerSSL, 0, $ip)))
						{
							$this->lastClientId++;
							$id = $this->lastClientId;

							stream_set_timeout($sock, 5);
							$this->arClients[$id] = new CXMPPClient($id, $sock);
							$this->arSockets[$id + $this->socketsClientsStartIndex] = $sock;

							$this->WriteToLog("Client connected (".$id.")", 5);
						}
					}
					else
					{
						$id = array_search($r, $this->arSockets);
						if ($id !== false && $id > 1)
						{
							if (CXMPPUtility::SelectDatabase($this->arClients[$id - $this->socketsClientsStartIndex]->GetClientDomain()))
							{
								$this->arClients[$id - $this->socketsClientsStartIndex]->Receive();
							}
							else
							{
								$this->arClients[$id - $this->socketsClientsStartIndex]->Disconnect();
								$this->WriteToLog("Client is disconnected because it was not possible to select the database (".$this->arClients[$id - $this->socketsClientsStartIndex]->GetClientDomain().")", 10);
							}
						}
						else
						{
							$sn1 = @stream_socket_get_name($r, true);
							$sn2 = @stream_socket_get_name($r, false);
							$this->WriteToLog("Debug: Socket is not found (".$sn1."-".$sn2.")", 10);
						}
					}
				}
			}
		}

		if (time() - $this->startClearPeriodTime > 30)
		{
			$this->__RefineClientsList();
			$this->WriteToLog("Number of clients connected = ".count($this->arClients), 10);
			$this->startClearPeriodTime = time();
		}

		if (time() - $this->startPeriodTime > 60)
		{
			$this->__ReportKernel();
			$this->startPeriodTime = time();
		}

		if (time() - $this->startLongPeriodTime > 600)
		{
			$this->__PingClients();
			$this->startLongPeriodTime = time();
			COption::SetOptionInt('xmpp', 'LastActivityDate', time());
		}
	}
}