I'm trying to add pecl-pthreads multithreading support to Ratchet WebSocket app.
This is my application:
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface
{
protected $clients;
public function __construct()
{
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})
";
}
public function onMessage(ConnectionInterface $from, $msg)
{
$dataIn = json_decode($msg);
switch ($dataIn->type) {
case 'test1':
echo '+t1 block start' . date(' H:i:s') . "
";
$test1 = new Test1();
$test1->start();
echo '+t1 block end' . date(' H:i:s') . "
";
break;
case 'test2':
echo '-t2 block start' . date(' H:i:s') . "
";
$test2 = new Test2();
$test2->start();
echo '-t2 block end' . date(' H:i:s') . "
";
break;
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected
";
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
echo "An error has occurred: {$e->getMessage()}
";
$conn->close();
}
}
This is Test1.php content:
<?php
namespace MyApp;
class Test1 extends \Thread
{
public function run()
{
echo '#Test1 thread start' . date(' H:i:s') . "
";
for ($i = 0; $i < 2; $i++) {
echo 1 . date(' H:i:s') . "
";
sleep(10);
}
echo '#Test1 thread end' . date(' H:i:s') . "
";
}
}
This is Test2.php content:
<?php
namespace MyApp;
class Test2 extends \Thread
{
public function run()
{
echo '#just Test2 run' . date(' H:i:s') . "
";
}
}
And this is JavaScript code:
var Websocket = new function () {
var ws
this.init = function () {
ws = new WebSocket(wsURL + '/test')
ws.onclose = function () {
setTimeout('Websocket.init()', 1000)
}
}
this.test1 = function () {
var token = {
type: 'test1'
}
ws.send(JSON.stringify(token))
}
this.test2 = function () {
var token = {
type: 'test2'
}
ws.send(JSON.stringify(token))
}
}
$(document).ready(function () {
Websocket.init()
})
var startTest = function () {
Websocket.test2()
Websocket.test2()
Websocket.test1()
Websocket.test2()
Websocket.test2()
}
The problem is that Test1 thread is bloking onMessage method of MyApp.
When I connect to my app with browser and run JavaScript startTest() function I get this CLI application output:
-t2 block start 20:08:48
#just Test2 run 20:08:48
-t2 block end 20:08:48
-t2 block start 20:08:48
#just Test2 run 20:08:48
-t2 block end 20:08:48
+t1 block start 20:08:48
#Test1 thread start 20:08:48
+t1 block end 20:08:48
1 20:08:48
1 20:08:58
#Test1 thread end 20:09:08
-t2 block start 20:09:08
#just Test2 run 20:09:08
-t2 block end 20:09:08
-t2 block start 20:09:08
#just Test2 run 20:09:08
-t2 block end 20:09:08
As you can see I send instant 5 messages from the browser to my application. But after test1 message there is a pause in execution of onMessage method until the end of execution of Test1 thread. Is it some kind of pthreads/ratchet bug or am I doing something wrong?
You send messages at one connection which means you have only single one thread. If you would like to check if multithreading is working - you should try to run that JS in next browser window / tab.
Cuz while test1 is blocking thread, else messages (2 messages test2 left) are waiting in queue. However if someone else will connect same time to the server he will not be a blocked - as he will gain separate thread. That is the power of multithreading in this case.