added new socketmanager, testing and exception ahndling not done yet
This commit is contained in:
parent
fc5a3e04b6
commit
fa899e87a8
@ -21,7 +21,7 @@ define('MANIACONTROL_PATH', __DIR__ . DIRECTORY_SEPARATOR);
|
|||||||
define('ManiaControlDir', MANIACONTROL_PATH);
|
define('ManiaControlDir', MANIACONTROL_PATH);
|
||||||
|
|
||||||
// Set process settings
|
// Set process settings
|
||||||
ini_set('memory_limit', '64M');
|
ini_set('memory_limit', '512M');
|
||||||
if (!ini_get('date.timezone') && function_exists('date_default_timezone_set')) {
|
if (!ini_get('date.timezone') && function_exists('date_default_timezone_set')) {
|
||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,6 @@ class CallbackManager {
|
|||||||
return $this->removeCallbackListener($this->callbackListenings, $listener);
|
return $this->removeCallbackListener($this->callbackListenings, $listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO better name (used only in customvotesPlugin)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the Callback Listener from the given Listeners Array
|
* Remove the Callback Listener from the given Listeners Array
|
||||||
*
|
*
|
||||||
@ -212,6 +210,9 @@ class CallbackManager {
|
|||||||
// Manage Timings
|
// Manage Timings
|
||||||
$this->maniaControl->getTimerManager()->manageTimings();
|
$this->maniaControl->getTimerManager()->manageTimings();
|
||||||
|
|
||||||
|
// Manage Socket Tickets
|
||||||
|
$this->maniaControl->getSocketManager()->tick();
|
||||||
|
|
||||||
// Server Callbacks
|
// Server Callbacks
|
||||||
if (!$this->maniaControl->getClient()) {
|
if (!$this->maniaControl->getClient()) {
|
||||||
return;
|
return;
|
||||||
|
@ -57,9 +57,10 @@ class Listening {
|
|||||||
* Trigger the Listener's Method with the given Array of Params
|
* Trigger the Listener's Method with the given Array of Params
|
||||||
*
|
*
|
||||||
* @param array $params
|
* @param array $params
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function triggerCallbackWithParams(array $params) {
|
public function triggerCallbackWithParams(array $params) {
|
||||||
call_user_func_array($this->getUserFunction(), $params);
|
return call_user_func_array($this->getUserFunction(), $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,7 @@ use ManiaControl\Players\PlayerManager;
|
|||||||
use ManiaControl\Plugins\PluginManager;
|
use ManiaControl\Plugins\PluginManager;
|
||||||
use ManiaControl\Server\Server;
|
use ManiaControl\Server\Server;
|
||||||
use ManiaControl\Settings\SettingManager;
|
use ManiaControl\Settings\SettingManager;
|
||||||
|
use ManiaControl\Sockets\SocketManager;
|
||||||
use ManiaControl\Statistics\StatisticManager;
|
use ManiaControl\Statistics\StatisticManager;
|
||||||
use ManiaControl\Update\UpdateManager;
|
use ManiaControl\Update\UpdateManager;
|
||||||
use ManiaControl\Utils\CommandLineHelper;
|
use ManiaControl\Utils\CommandLineHelper;
|
||||||
@ -166,7 +167,8 @@ class ManiaControl implements CallbackListener, CommandListener, TimerListener {
|
|||||||
private $requestQuitMessage = null;
|
private $requestQuitMessage = null;
|
||||||
|
|
||||||
/** @var EchoManager $echoManager */
|
/** @var EchoManager $echoManager */
|
||||||
private $echoManager = null;
|
private $echoManager = null;
|
||||||
|
private $socketManager = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new ManiaControl instance
|
* Construct a new ManiaControl instance
|
||||||
@ -186,6 +188,7 @@ class ManiaControl implements CallbackListener, CommandListener, TimerListener {
|
|||||||
$this->fileReader = new AsynchronousFileReader($this);
|
$this->fileReader = new AsynchronousFileReader($this);
|
||||||
$this->billManager = new BillManager($this);
|
$this->billManager = new BillManager($this);
|
||||||
$this->settingManager = new SettingManager($this);
|
$this->settingManager = new SettingManager($this);
|
||||||
|
$this->socketManager = new SocketManager($this);
|
||||||
$this->statisticManager = new StatisticManager($this);
|
$this->statisticManager = new StatisticManager($this);
|
||||||
$this->manialinkManager = new ManialinkManager($this);
|
$this->manialinkManager = new ManialinkManager($this);
|
||||||
$this->actionsMenu = new ActionsMenu($this);
|
$this->actionsMenu = new ActionsMenu($this);
|
||||||
@ -293,6 +296,15 @@ class ManiaControl implements CallbackListener, CommandListener, TimerListener {
|
|||||||
return $this->echoManager;
|
return $this->echoManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the socket manager
|
||||||
|
*
|
||||||
|
* @return SocketManager
|
||||||
|
*/
|
||||||
|
public function getSocketManager() {
|
||||||
|
return $this->socketManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the chat
|
* Return the chat
|
||||||
*
|
*
|
||||||
|
@ -112,6 +112,8 @@ class PlayerManager implements CallbackListener, TimerListener, EchoListener {
|
|||||||
// Echo Warn Command (Usage: sendEcho json_encode("player" => "loginName")
|
// Echo Warn Command (Usage: sendEcho json_encode("player" => "loginName")
|
||||||
$this->maniaControl->getEchoManager()->registerEchoListener(self::ECHO_WARN_PLAYER, $this, function ($params) {
|
$this->maniaControl->getEchoManager()->registerEchoListener(self::ECHO_WARN_PLAYER, $this, function ($params) {
|
||||||
$this->playerActions->warnPlayer(null, $params->player, false);
|
$this->playerActions->warnPlayer(null, $params->player, false);
|
||||||
|
|
||||||
|
return "abcdef";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: Lukas
|
|
||||||
* Date: 20.06.2015
|
|
||||||
* Time: 22:44
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace ManiaControl\Sockets;
|
namespace ManiaControl\Sockets;
|
||||||
|
|
||||||
|
|
||||||
use ManiaControl\Callbacks\Listening;
|
use ManiaControl\Callbacks\Listening;
|
||||||
use ManiaControl\ManiaControl;
|
use ManiaControl\ManiaControl;
|
||||||
use React\EventLoop\Factory;
|
use React\EventLoop\Factory;
|
||||||
|
use React\EventLoop\LoopInterface;
|
||||||
|
use React\Socket\Connection;
|
||||||
|
use React\Socket\ConnectionException;
|
||||||
|
use React\Socket\Server;
|
||||||
|
|
||||||
class SocketHandler {
|
/**
|
||||||
|
* Class for managing Socket Callbacks
|
||||||
|
*
|
||||||
|
* @author ManiaControl Team <mail@maniacontrol.com>
|
||||||
|
* @copyright 2014-2015 ManiaControl Team
|
||||||
|
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
||||||
|
*/
|
||||||
|
class SocketManager {
|
||||||
|
|
||||||
/** @var ManiaControl $maniaControl */
|
/** @var ManiaControl $maniaControl */
|
||||||
private $maniaControl = null;
|
private $maniaControl = null;
|
||||||
|
|
||||||
|
/** @var LoopInterface $loop */
|
||||||
|
private $loop = null;
|
||||||
|
|
||||||
/** @var Listening[] $socketListenings */
|
/** @var Listening[] $socketListenings */
|
||||||
private $socketListenings = array();
|
private $socketListenings = array();
|
||||||
|
|
||||||
|
/** @var Server $socket */
|
||||||
|
private $socket = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Socket Handler Instance
|
* Create a new Socket Handler Instance
|
||||||
*
|
*
|
||||||
@ -28,37 +39,152 @@ class SocketHandler {
|
|||||||
public function __construct(ManiaControl $maniaControl) {
|
public function __construct(ManiaControl $maniaControl) {
|
||||||
$this->maniaControl = $maniaControl;
|
$this->maniaControl = $maniaControl;
|
||||||
|
|
||||||
|
$this->createSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createSocket() {
|
/**
|
||||||
$loop = Factory::create();
|
* Register a new Socket Listener
|
||||||
$server = stream_socket_server('tcp://127.0.0.1:19999');
|
*
|
||||||
stream_set_blocking($server, 0);
|
* @param string $callbackName
|
||||||
|
* @param SocketListener $listener
|
||||||
|
* @param string $method
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function registerSocketListener($echoName, SocketListener $listener, $method) {
|
||||||
|
if (!Listening::checkValidCallback($listener, $method)) {
|
||||||
|
$listenerClass = get_class($listener);
|
||||||
|
trigger_error("Given Listener '{$listenerClass}' can't handle Callback '{$echoName}': No callable Method '{$method}'!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$loop->addReadStream($server, function ($server) use ($loop) {
|
if (!array_key_exists($echoName, $this->socketListenings)) {
|
||||||
$conn = stream_socket_accept($server);
|
$this->socketListenings[$echoName] = new Listening($listener, $method);
|
||||||
$data = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nHi\n";
|
} else {
|
||||||
$loop->addWriteStream($conn, function ($conn) use (&$data, $loop) {
|
//TODO say which is already listening and other stuff
|
||||||
$written = fwrite($conn, $data);
|
trigger_error("Only one Listener can listen on a specific Socket Message");
|
||||||
if ($written === strlen($data)) {
|
}
|
||||||
fclose($conn);
|
|
||||||
$loop->removeStream($conn);
|
return true;
|
||||||
} else {
|
}
|
||||||
$data = substr($data, 0, $written);
|
|
||||||
}
|
/**
|
||||||
|
* Trigger a specific Callback
|
||||||
|
*
|
||||||
|
* @param mixed $callback
|
||||||
|
*/
|
||||||
|
public function triggerSocketCallback($callbackName) {
|
||||||
|
if (!array_key_exists($callbackName, $this->socketListenings)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = func_get_args();
|
||||||
|
$params = array_slice($params, 1, null, true);
|
||||||
|
|
||||||
|
$listening = $this->socketListenings[$callbackName];
|
||||||
|
/** @var Listening $listening */
|
||||||
|
return $listening->triggerCallbackWithParams($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister a Socket Listener
|
||||||
|
*
|
||||||
|
* @param SocketListener $listener
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function unregisterEchoListener(SocketListener $listener) {
|
||||||
|
return $this->removeSocketListener($this->socketListenings, $listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the Socket Listener from the given Listeners Array
|
||||||
|
*
|
||||||
|
* @param Listening[] $listeningsArray
|
||||||
|
* @param SocketListener $listener
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function removeSocketListener(array &$listeningsArray, SocketListener $listener) {
|
||||||
|
$removed = false;
|
||||||
|
foreach ($listeningsArray as &$listening) {
|
||||||
|
if ($listening->listener === $listener) {
|
||||||
|
unset($listening);
|
||||||
|
$removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates The Socket
|
||||||
|
*/
|
||||||
|
private function createSocket() {
|
||||||
|
try {
|
||||||
|
$this->loop = Factory::create();
|
||||||
|
$this->socket = new Server($this->loop);
|
||||||
|
|
||||||
|
$this->socket->on('error', function ($e) {
|
||||||
|
//TODO error handling
|
||||||
|
var_dump($e);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
$loop->addPeriodicTimer(5, function () {
|
$this->socket->on('connection', function (Connection $connection) {
|
||||||
$memory = memory_get_usage() / 1024;
|
$buffer = '';
|
||||||
$formatted = number_format($memory, 3) . 'K';
|
$connection->on('data', function ($data) use (&$buffer, &$connection) {
|
||||||
echo "Current memory usage: {$formatted}\n";
|
$buffer .= $data;
|
||||||
});
|
$arr = explode("\n", $buffer, 2); // much haxy.
|
||||||
|
while (count($arr) == 2 && strlen($arr[1]) >= (int) $arr[0]) {
|
||||||
|
// received full message
|
||||||
|
$len = (int) $arr[0];
|
||||||
|
$msg = substr($arr[1], 0, $len); // clip msg
|
||||||
|
$buffer = substr($buffer, strlen((string) $len) + 1 /* newline */ + $len); // clip buffer
|
||||||
|
|
||||||
$loop->tick();
|
//TODO pass and port management
|
||||||
|
// Decode Message
|
||||||
|
$data = openssl_decrypt($msg, 'aes-192-cbc', 'testpass123', OPENSSL_RAW_DATA, 'kZ2Kt0CzKUjN2MJX');
|
||||||
|
$data = json_decode($data);
|
||||||
|
|
||||||
|
if ($data == null) {
|
||||||
|
$data = array("error" => true, "data" => "Data is not provided as an valid AES-196-encrypted encrypted JSON");
|
||||||
|
} else if (!property_exists($data, "method") || !property_exists($data, "data")) {
|
||||||
|
$data = array("error" => true, "data" => "Invalid Message");
|
||||||
|
} else {
|
||||||
|
$answer = $this->triggerSocketCallback($data->method, $data);
|
||||||
|
//Prepare Response
|
||||||
|
if (!$answer) {
|
||||||
|
$data = array("error" => true, "data" => "No listener or response on the given Message");
|
||||||
|
} else {
|
||||||
|
$data = array("error" => false, "data" => $answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Encode, Encrypt and Send Response
|
||||||
|
$data = json_encode($data);
|
||||||
|
$data = openssl_encrypt($data, 'aes-192-cbc', 'testpass123', OPENSSL_RAW_DATA, 'kZ2Kt0CzKUjN2MJX');
|
||||||
|
$connection->write(strlen($data) . "\n" . $data);
|
||||||
|
|
||||||
|
// next msg
|
||||||
|
$arr = explode("\n", $buffer, 2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//TODO port
|
||||||
|
$this->socket->listen(19999, getHostByName(getHostName())); // exceptions are just thrown right? why does it not work with local ip? because you bind to your loopback adapter k
|
||||||
|
|
||||||
|
// so that aint it.. xD^^ maybe because it is not in an apache environemnt or smth
|
||||||
|
// this lib should never run in such an env but the periodictimer works? :O thats actually cool xD ye xD
|
||||||
|
} catch (ConnectionException $e) {
|
||||||
|
//TODO proper handling
|
||||||
|
var_dump($e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tick() {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes Data on every ManiaControl Tick, don't call this Method
|
||||||
|
*/
|
||||||
|
public function tick() {
|
||||||
|
$this->loop->tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user