diff --git a/app/assets/js/movim_websocket.js b/app/assets/js/movim_websocket.js index b21c43734..8c29b184e 100755 --- a/app/assets/js/movim_websocket.js +++ b/app/assets/js/movim_websocket.js @@ -8,6 +8,10 @@ WebSocket.prototype.unregister = function() { this.send(JSON.stringify({'func' : 'unregister'})); }; +WebSocket.prototype.register = function(host) { + this.send(JSON.stringify({'func' : 'register', 'host' : host})); +}; + WebSocket.prototype.admin = function(key) { this.send(JSON.stringify({'func' : 'admin', 'key' : key})); }; @@ -20,6 +24,7 @@ WebSocket.prototype.admin = function(key) { var MovimWebsocket = { connection: null, attached: new Array(), + registered: new Array(), unregistered: false, launchAttached : function() { @@ -28,6 +33,12 @@ var MovimWebsocket = { } }, + launchRegistered : function() { + for(var i = 0; i < MovimWebsocket.registered.length; i++) { + MovimWebsocket.registered[i](); + } + }, + init : function() { if(SECURE_WEBSOCKET) { var uri = 'wss://' + BASE_HOST + '/ws/'; @@ -49,7 +60,7 @@ var MovimWebsocket = { if(obj != null) { if(obj.func == 'registered') { - MovimWebsocket.launchAttached(); + MovimWebsocket.launchRegistered(); } if(obj.func == 'disconnected') { @@ -101,6 +112,12 @@ var MovimWebsocket = { } }, + register : function(func) { + if(typeof(func) === "function") { + this.registered.push(func); + } + }, + clearAttached : function() { this.attached = new Array(); }, diff --git a/app/widgets/Login/Login.php b/app/widgets/Login/Login.php index 8527e9a32..f674994e1 100755 --- a/app/widgets/Login/Login.php +++ b/app/widgets/Login/Login.php @@ -199,13 +199,10 @@ class Login extends WidgetBase } // We try to get the domain - $dns = dns_get_record('_xmpp-client._tcp.'.$host); + $domain = \Moxl\Utils::getDomain($host); - if(isset($dns[0]['target']) && $dns[0]['target'] != null) - $domain = $dns[0]['target']; - else { - $domain = $host; - } + // We launch the XMPP socket + RPC::call('register', $host); // We create a new session or clear the old one $s = Sessionx::start(); diff --git a/app/widgets/Login/login.js b/app/widgets/Login/login.js index dacdc9ba4..73ccd14ed 100755 --- a/app/widgets/Login/login.js +++ b/app/widgets/Login/login.js @@ -13,10 +13,11 @@ var Login = { form.onsubmit = function(e) { e.preventDefault(); + // We register the socket + MovimWebsocket.connection.register(this.querySelector('input#login').value.replace(/.*@/, "")); + var button = this.querySelector('input[type=submit]'); button.value = button.dataset.loading; - - eval(this.dataset.action); localStorage.username = document.querySelector('#login').value; Login.rememberSession(localStorage.username); @@ -157,6 +158,12 @@ MovimWebsocket.attach(function() } }); +MovimWebsocket.register(function() +{ + form = document.querySelector('form[name="login"]'); + eval(form.dataset.action); +}); + movim_add_onload(function() { /* Dump cache variables in localStorage */ for ( var i = 0, len = localStorage.length; i < len; ++i ) { diff --git a/composer.json b/composer.json index af93a6f36..c74bebf7c 100755 --- a/composer.json +++ b/composer.json @@ -19,8 +19,8 @@ "cboden/ratchet": "0.3.*", "react/child-process": "0.5.*@dev", - "ratchet/pawl": "dev-master", "react/socket-client": "0.4.*@dev", + "ratchet/pawl": "dev-master", "forxer/Gravatar": "~1.2", "respect/validation": "0.8.*" diff --git a/jajax.php b/jajax.php deleted file mode 100755 index 84cb3c057..000000000 --- a/jajax.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * @version 1.0 - * @date 7 November 2010 - * - * Copyright (C)2010 MOVIM team - * - * See the file `COPYING' for licensing information. - */ - -define('DOCUMENT_ROOT', dirname(__FILE__)); -define('DOCTYPE','application/json'); -require_once(DOCUMENT_ROOT.'/bootstrap.php'); -try { - $bootstrap = new Bootstrap(); - $booted = $bootstrap->boot(); - - set_time_limit(200); - - $polling = true; - - $rpc = new RPC(); - $rpc->handle_json(); - - // Closing stuff - WidgetWrapper::destroyInstance(); -} catch(\Exception $e) { - if(isset($_GET['fail_safe']) && (int)$_GET['fail_safe']) { - $rpc = new RPC(); - $rpc->handle_json(); - } - - print $e->getMessage(); -} -?> diff --git a/linker.php b/linker.php index 020390643..59a4f1f75 100755 --- a/linker.php +++ b/linker.php @@ -5,32 +5,20 @@ define('DOCUMENT_ROOT', dirname(__FILE__)); require_once(DOCUMENT_ROOT.'/bootstrap.php'); gc_enable(); +ini_set('xdebug.max_nesting_level', 300); $bootstrap = new Bootstrap(); $booted = $bootstrap->boot(); -//fwrite(STDERR, colorize(getenv('sid'), 'yellow')." booted : ".\sizeToCleanSize(memory_get_usage())."\n"); - $loop = React\EventLoop\Factory::create(); -//fwrite(STDERR, colorize(getenv('sid'), 'yellow')." loop : ".\sizeToCleanSize(memory_get_usage())."\n"); - /*$dnsResolverFactory = new React\Dns\Resolver\Factory(); -$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);*/ +$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop); +$connector = new React\SocketClient\Connector($loop, $dns);*/ $connector = new Ratchet\Client\Factory($loop); - -//fwrite(STDERR, colorize(getenv('sid'), 'yellow')." connector : ".\sizeToCleanSize(memory_get_usage())."\n"); - $stdin = new React\Stream\Stream(STDIN, $loop); -//fwrite(STDERR, colorize(getenv('sid'), 'yellow')." stdin : ".\sizeToCleanSize(memory_get_usage())."\n"); - -$cd = new \Modl\ConfigDAO(); -$config = $cd->get(); - -//fwrite(STDERR, colorize(getenv('sid'), 'yellow')." config : ".\sizeToCleanSize(memory_get_usage())."\n"); - fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets before : ".\sizeToCleanSize(memory_get_usage())."\n"); // We load and register all the widgets @@ -39,47 +27,134 @@ $wrapper->registerAll(true); fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets : ".\sizeToCleanSize(memory_get_usage())."\n"); -$connector($config->websocketurl, array('xmpp'))->then(function($conn) use (&$stdin, $loop) { +$conn = null; + +//$parser = new \Moxl\Parser; + +$buffer = ''; + +$stdin_behaviour = function ($data) use (/*&*/&$conn, $loop, &$buffer, &$connector, &$xmpp_behaviour/*, &$parser*/) { + //if(!isset($buffer)) $buffer = ''; + if(substr($data, -1) == "") { + $messages = explode("", $buffer . substr($data, 0, -1)); + $buffer = ''; + + //if(isset($conn)) $conn->pause(); + + foreach ($messages as $message) { + #fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received from the browser', 'green')."\n"); + + $msg = json_decode($message); + + if(isset($msg)) { + if($msg->func == 'message' && $msg->body != '') { + $msg = $msg->body; + } elseif($msg->func == 'unregister') { + $conn->close(); + } elseif($msg->func == 'register') { + $cd = new \Modl\ConfigDAO(); + $config = $cd->get(); + + /*$domain = \Moxl\Utils::getDomain($msg->host); + fwrite(STDERR, colorize('open a socket to '.$domain, 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); + $connector->create($domain, 5222)->then($xmpp_behaviour);*/ + $connector($config->websocketurl, array('xmpp'))->then($xmpp_behaviour); + } + } else { + return; + } + + $rpc = new \RPC(); + $rpc->handle_json($msg); + + $msg = json_encode(\RPC::commit()); + \RPC::clear(); + + $xml = \Moxl\API::commit(); + \Moxl\API::clear(); + + if(!empty($xml)) { + //$conn->write(trim($xml)); + $conn->send(trim($xml)); + fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); + } + + if(!empty($msg)) { + echo base64_encode(gzcompress($msg, 9)).""; + #fwrite(STDERR, colorize($msg, 'yellow')." : ".colorize('sent to the browser', 'green')."\n"); + } + } + + //if(isset($conn)) $conn->resume(); + } else { + $buffer .= $data; + } +}; + +//$xmpp_behaviour = function (React\Stream\Stream $stream) use (&$conn, $loop, &$stdin, $stdin_behaviour, $parser) { +$xmpp_behaviour = function (Ratchet\Client\WebSocket $stream) use (&$conn, $loop, &$stdin, $stdin_behaviour/*, $parser*/) { + $conn = $stream; fwrite(STDERR, colorize(getenv('sid'), 'yellow')." : ".colorize('linker launched', 'blue')."\n"); fwrite(STDERR, colorize(getenv('sid'), 'yellow')." launched : ".\sizeToCleanSize(memory_get_usage())."\n"); - - $conn->on('message', function($message) use ($conn, $loop) { - if($message != '') { - #fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n"); + $stdin->removeAllListeners('data'); + $stdin->on('data', $stdin_behaviour); + + $conn->bufferSize = 4096*256; + $conn->on('message', function($message) use (&$conn, $loop, $parser/*, $stream*/) { + + //$conn->pause(); + + if(!empty($message)) { + fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n"); + + $restart = false; + if($message == '') { $conn->close(); $loop->stop(); + } elseif($message == "") { + stream_set_blocking($conn->stream, 1); + $out = stream_socket_enable_crypto($conn->stream, 1, STREAM_CRYPTO_METHOD_TLS_CLIENT); + stream_set_blocking($conn->stream, 0); + $restart = true; } \Moxl\API::clear(); \RPC::clear(); - //fwrite(STDERR, colorize(getenv('sid'), 'yellow')." before handle : ".\sizeToCleanSize(memory_get_usage())."\n"); - + /*if(!$parser->parse($message)) { + fwrite(STDERR, colorize(getenv('sid'), 'yellow')." ".$parser->getError()); + }*/ \Moxl\Xec\Handler::handleStanza($message); - //fwrite(STDERR, colorize(getenv('sid'), 'yellow')." after handle : ".\sizeToCleanSize(memory_get_usage())."\n"); - - $xml = \Moxl\API::commit(); - \Moxl\API::clear(); - - //fwrite(STDERR, colorize(getenv('sid'), 'yellow')." after commit : ".\sizeToCleanSize(memory_get_usage())."\n"); + if($restart) { + $session = \Sessionx::start(); + \Moxl\Stanza\Stream::init($session->domain); + $restart = false; + } $msg = \RPC::commit(); \RPC::clear(); if(!empty($msg)) { - $msg = json_encode($msg); - #fwrite(STDERR, colorize($msg, 'yellow')." : ".colorize('sent to browser', 'green')."\n"); - echo base64_encode(gzcompress($msg, 9)).""; + echo base64_encode(gzcompress(json_encode($msg), 9)).""; + #fwrite(STDERR, colorize($msg.' '.strlen($msg), 'yellow')." : ".colorize('sent to browser', 'green')."\n"); } + $xml = \Moxl\API::commit(); + \Moxl\API::clear(); + if(!empty($xml)) { - #fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); + //$conn->write(trim($xml)); $conn->send(trim($xml)); + fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); } + + $loop->tick(); } + + //$conn->resume(); }); $conn->on('error', function($msg) use ($conn, $loop) { @@ -90,95 +165,15 @@ $connector($config->websocketurl, array('xmpp'))->then(function($conn) use (&$st $loop->stop(); }); - $stdin->removeAllListeners('data'); - $stdin->on('data', function ($data) use ($conn, $loop, &$buffer) { - // A little bit of signalisation to use properly the buffer - if(substr($data, -1) == "") { - $messages = explode("", $buffer . substr($data, 0, -1)); - $buffer = ''; - - foreach ($messages as $message) { - #fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received from the browser', 'green')."\n"); - - $msg = json_decode($message); - - if($msg->func == 'message' && $msg->body != '') { - $msg = $msg->body; - } elseif($msg->func == 'unregister') { - $conn->close(); - $loop->stop(); - } else { - return; - } - - $rpc = new \RPC(); - $rpc->handle_json($msg); - - $xml = \Moxl\API::commit(); - \Moxl\API::clear(); - - if(!empty($xml)) { - #fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); - $conn->send(trim($xml)); - } - - $msg = json_encode(\RPC::commit()); - \RPC::clear(); - - if(!empty($msg)) { - #fwrite(STDERR, colorize($msg, 'yellow')." : ".colorize('sent to the browser', 'green')."\n"); - echo base64_encode(gzcompress($msg, 9)).""; - } - } - } else { - $buffer .= $data; - } - }); - // And we say that we are ready ! $obj = new \StdClass; $obj->func = 'registered'; echo base64_encode(gzcompress(json_encode($obj), 9)).""; -}); +}; -// Fallback event, when the WebSocket is not enabled, -// we still handle browser to Movim requests -$stdin->on('data', function ($data) use ($loop) { - if(!isset($buffer)) $buffer = ''; - if(substr($data, -1) == "") { - $messages = explode("", $buffer . substr($data, 0, -1)); - $buffer = ''; - - foreach ($messages as $message) { - #fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received from the browser', 'green')."\n"); - - $msg = json_decode($message); - - if(isset($msg)) { - if($msg->func == 'message' && $msg->body != '') { - $msg = $msg->body; - } elseif($msg->func == 'unregister') { - $loop->stop(); - } - } else { - return; - } - - $rpc = new \RPC(); - $rpc->handle_json($msg); - - $msg = json_encode(\RPC::commit()); - \RPC::clear(); - - if(!empty($msg)) { - #fwrite(STDERR, colorize($msg, 'yellow')." : ".colorize('sent to the browser', 'green')."\n"); - echo base64_encode(gzcompress($msg, 9)).""; - } - } - } else { - $buffer .= $data; - } -}); +$stdin->on('data', $stdin_behaviour); +$stdin->on('error', function() use($loop) { $loop->stop(); } ); +$stdin->on('close', function() use($loop) { $loop->stop(); } ); $loop->run();