I followed this tutorial socketo/push to push messages from the server to the client in real time. I'm using the CodeIgniter framework. These are my files:
push-server.php
$loop = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means
// the only client that can connect
// is itself
$pull->on('message', array($pusher, 'onMessage'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server('0.0.0.0:8080', $loop);
/*
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means
// remotes can connect
*/
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
I commented the $webSock->listen() line because it was throwing an error and in a git issue someone has commented that this was because an update in the react/zmq library, so that is the only line different to the tutorial.
controller.php
public function post()
{
$entryData = array(
'category' => 'kittensCategory',
'title' => 'Title'
);
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send(json_encode($entryData));
}
This is the function that I'm calling and that should push a message to my pusher class but it does nothing.
I don't know what's the problem, my client is connecting correctly and the pusher is working good in the subscription method, so it has to be something in the push or the pull.
I have been trying to solve this for 2 weeks now but I don't have a clue, any comment would be awesome, thanks.
Related
There's page in http://socketo.me/docs/origin talking about it, but it's completly unclear how to implement it.
This is my current code (from the tutorial at http://socketo.me/docs/push):
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onBlogEntry'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server('0.0.0.0:8080', $loop); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
Following the tutorial at http://socketo.me/docs/origin it says that i should add the variable $checkedApp to the constructor of the class HttpServer. I checked the souce code of this class, and it uses only one param in the __constructor(), and as you can see i already passed a value to this constructor, which is a instance of the class WsServer. Also the class MyHttpApp does not exist.
Aftet i searched a bit in the souce code i found the file App.php located at https://github.com/ratchetphp/Ratchet/blob/master/src/Ratchet/App.php and to implement the OriginChecker i just need to change the value of the variable $webServer to the value bellow:
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\Http\OriginCheck(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
),
array('mydomain.com') //this is the only domain that can connect to the websocket
)
),
$webSock
);
I am trying to get the ratchet push tutorial to work.
http://socketo.me/docs/push
I am doing exactly what the tutorial is saying but no messages will be received by my subscriber.
My server.php
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onBlogEntry'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server('0.0.0.0:8080', $loop); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
My addblog.php
<?php
// post.php ???
// This all was here before ;)
$entryData = array(
'category' => 'kittensCategory'
, 'title' => 'Test'
, 'article' => 'Test'
, 'when' => time()
);
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send(json_encode($entryData));
And my listener.html
<script src="autobahn.js"></script>
<script>
var conn = new ab.Session('ws://localhost:8080',
function() {
conn.subscribe('kittensCategory', function(topic, data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
console.log('New article published to category "' + topic + '" : ' + data.title);
});
},
function() {
console.warn('WebSocket connection closed');
},
{'skipSubprotocolCheck': true}
);
</script>
And my Pusher.php
<?php
namespace MyApp;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
class Pusher implements WampServerInterface {
/**
* A lookup of all the topics clients have subscribed to
*/
protected $subscribedTopics = array();
public function onSubscribe(ConnectionInterface $conn, $topic) {
echo "Hello to: ".$topic;
$this->subscribedTopics[$topic->getId()] = $topic;
}
/**
* #param string JSON'ified string we'll receive from ZeroMQ
*/
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
echo "gallogallo";
// If the lookup topic object isn't set there is no one to publish to
if (!array_key_exists($entryData['category'], $this->subscribedTopics))
{
return;
}
$topic = $this->subscribedTopics[$entryData['category']];
// re-send the data to all the clients subscribed to that category
$topic->broadcast($entryData);
}
I do not receive any errors or warnings.
When I try to call addblog.php nothing is happening and I do not understand why.
Any hints maybe? I am testing this with XAMPP and Windows 10.
I don't know why, but it is working very well on another system...
I try to make websocket server with rachet and pawl.
I read doc ratchet with ZeroMQ http://socketo.me/docs/push
But can't run it with Pawl https://github.com/ratchetphp/Pawl
I create client:
<script>
var ws = new WebSocket('ws://site.ll:8008/?user=tester01');
ws.onmessage = function(evt) { console.log(evt.data); };
</script>
Create worker:
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/Pusher.php';
$loop = React\EventLoop\Factory::create();
$pusher = new Pusher;
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server('0.0.0.0:8008', $loop);
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
Pusher class usgin the same like in tutorial http://socketo.me/docs/push#zeromq_messages
Using post.php to send message through ws:
$localsocket = 'tcp://127.0.0.1:1235';
$user = 'tester01';
$message = 'test';
$instance = stream_socket_client($localsocket);
fwrite($instance, json_encode(['user' => $user, 'message' => $message]) . "\n");
But still can't understand how to create tcp server withou ZeroMQ, like this part:
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:1235');
$pull->on('message', array($pusher, 'onBlogEntry'));
If you don't wan't to use ZeroMQ, you can use the same React mecanisms Ratchet uses.
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/Pusher.php';
use React\EventLoop\Factory;
use React\Socket\ConnectionInterface;
use React\Socket\Server;
$loop = Factory::create();
$pusher = new Pusher;
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server('0.0.0.0:8080', $loop);
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
// Set up an incoming TCP socket to receive the messages to push
$inSocket = new Server('127.0.0.1:5555', $loop);
$inSocket->on('connection', function (ConnectionInterface $conn) use ($pusher) {
// New data arrives at the socket
$conn->on('data', function ($data) use ($conn, $pusher) {
// Push the new blog entry update
$pusher->onBlogEntry($data);
// Close the incoming connection when the message is consumed
$conn->close();
});
});
$loop->run();
Doing with Pawl next and load on github:
https://github.com/Shkarbatov/WebSocketPHPRatchet
I'm trying to get a request to my server via a websocket, and return a reply from the server. This is "sort of" working, however I can only do this once, any extra requests just hang somewhere.
Server Bind:
$pull = $context->getSocket(ZMQ::SOCKET_REP);
$pull->bind('tcp://127.0.0.1:5552');
$pull->on('message', array($pusher, 'onPull'));
$pull->recv();
$pull->send('back');
I have a static PHP file on my server, which when I run, want to return the reply from the server:
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_REQ, 'Sock');
$socket->connect("tcp://localhost:5552");
$socket->send('sending');
$message = $socket->recv();
echo "$message";
Now when I boot the server and run my php file, I get the "back" response back. However when I try to run it again it just hangs. I'm receiving the request each time?
Also, can anyone explain the $pull->on bit to me, I cannot find anywhere what it does.
Full server code:
<?php
require './vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new MyApp\Pusher;
$context = new React\ZMQ\Context($loop);
$push = $context->getSocket(ZMQ::SOCKET_PULL);
$push->bind('tcp://127.0.0.1:5555');
$push->on('message', array($pusher, 'onNewPush'));
$pull = $context->getSocket(ZMQ::SOCKET_REP);
$pull->bind('tcp://127.0.0.1:5552');
$pull->on('message', array($pusher, 'onPull'));
$pull->recv();
$pull->send('back');
$webSock = new React\Socket\Server($loop);
$webSock->listen(8080, '0.0.0.0');
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
$pusher
)
),
$webSock
);
$loop->run();
I think something like this should do the job:
$pull->on(
'message',
function ($message) use ($pull) {
$pull->send('response');
}
);
In any case, whether you use an anonymous function like above or an object/method pair, you need access to $pull, because that is the communication channel that allows you to send messages. The example at http://socketo.me/docs/push, which seems to be the base of your code, doesn't need that, since it uses a pull socket, which only receives messages.
Following this instruction http://socketo.me/docs/push I had this working.
However, I'd like my service to be compatible with older browsers as well (IE 8 etc), so I need to use a flash fallback (like web_socket.js or similar) to do this:
function initPull() {
var conn = new ab.Session(
// The host (our Ratchet WebSocket server) to
'ws://'+PUSH_SOCKET_SERVER+':'+PUSH_SOCKET_PORT+'/',
// Once the connection has been established
function() {
conn.subscribe(TOPIC_PREFIX+rID, function(topic, data) {
//Trigger action
aTrigger(data);
});
},
// When the connection is closed
function() {
console.warn('WebSocket connection closed');
},
// Additional parameters, we're ignoring the WAMP sub-protocol for older browsers
{
'skipSubprotocolCheck': true
}
);
}
Ratchet supports web-socket-js, which is a natural polyfill. The ZMQ code is on the server side and will still be executed if your client is using native WebSockets or the Flash polyfill.
Keep your code from the Push tutorial as is, add web-socket-js code to your client and then see the code from the FlashPolicy component.
For a bit more involved example, see this example on how to server Flash Policy files without having to run two separate processes.
I believe I have done just what you suggested. The idea is to combine chat server with push messages. This all works except flash polyfill. Here is my server code:
//This is a server to handle both WAMP chat messages and PUSH messages
use Ratchet\Server\IoServer;
use Ratchet\Server\FlashPolicy;
use Ratchet\WebSocket\WsServer;
use Ratchet\Wamp\ServerProtocol;
use React\EventLoop\Factory;
use React\Socket\Server as Reactor;
use React\ZMQ\Context;
use Ratchet\Wamp\WampServer;
use Ratchet\Cookbook\OpenPubSub;
use Ratchet\Website\PortLogger;
use Ratchet\Cookbook\NullComponent;
use Ratchet\Cookbook\MessageLogger;
use Ratchet\Push\Pusher;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Composer: The greatest thing since sliced bread
require dirname(__DIR__) . '/vendor/autoload.php';
// Setup logging
$stdout = new StreamHandler('php://stdout');
$logout = new Logger('SockOut');
$login = new Logger('Sock-In');
$login->pushHandler($stdout);
$logout->pushHandler($stdout);
// The all mighty event loop
$loop = Factory::create();
// This little thing is to check for connectivity...
// As a case study, when people connect on port 80, we're having them
// also connect on port 9000 and increment a counter if they connect.
// Later, we can publish the results and find out if WebSockets over
// a port other than 80 is viable (theory is blocked by firewalls).
$context = new Context($loop);
$push = $context->getSocket(ZMQ::SOCKET_PUSH);
$push->connect('tcp://127.0.0.1:8080');
// Setup our Ratchet ChatRoom application
$webSock = new Reactor($loop);
$webSock->listen(8080, '0.0.0.0');
$webServer = new IoServer( // Basic I/O with clients, aww yeah
new WsServer( // Boom! WebSockets
new PortLogger($push, 80, // Compare vs the almost over 9000 conns
new MessageLogger( // Log events in case of "oh noes"
new WampServer(
new OpenPubSub
)
, $login
, $logout
)
)
)
, $webSock
);
// Allow Flash sockets (Internet Explorer) to connect to our app
$flashSock = new Reactor($loop);
$flashSock->listen(843, '0.0.0.0');
$policy = new FlashPolicy;
$policy->addAllowedAccess('*', 80);
$policy->addAllowedAccess('*', 8080);
$policy->addAllowedAccess('*', 8081);
$webServer = new IoServer($policy, $flashSock);
$logSock = new Reactor($loop);
$logSock->listen(9000, '0.0.0.0');
$zLogger = new IoServer(
new WsServer(
new MessageLogger(
new PortLogger($push, 9000, new NullComponent)
)
)
, $logSock
);
$pusher = new Pusher;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onMsg'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server($loop);
$webSock->listen(8081, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
new Ratchet\WebSocket\WsServer(
new MessageLogger(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
// GO GO GO!
echo "[".Date("Y-m-d H:i:s")."] VPCserver started...\n";
$loop->run();