I am using ratchet along with laravel.
This is my main socket server:
<?php
/**
* Created by PhpStorm.
* User: harshvardhangupta
* Date: 27/05/16
* Time: 1:40 PM
*/
use App\Http\Controllers\SocketController;
require './vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new SocketController();
// 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($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();
and this is my socket controller:
<?php
namespace App\Http\Controllers;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\Topic;
use Ratchet\Wamp\WampServerInterface;
class SocketController implements WampServerInterface
{
/**
* A lookup of all the topics clients have subscribed to
*/
protected $subscribedTopics = array();
public function onSubscribe(ConnectionInterface $conn, $topic) {
echo"on";
$this->subscribedTopics[$topic->getId()] = $topic;
}
/**
* #param string JSON'ified string we'll receive from ZeroMQ
*/
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
// 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);
}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
}
public function onOpen(ConnectionInterface $conn) {
echo"open";
}
public function onClose(ConnectionInterface $conn) {
echo "close";
}
/* The rest of our methods were as they were, omitted from docs to save space */
/**
* If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
* the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
* #param ConnectionInterface $conn
* #param \Exception $e
* #throws \Exception
*/
function onError(ConnectionInterface $conn, \Exception $e)
{
// TODO: Implement onError() method.
}
/**
* An RPC call has been received
* #param \Ratchet\ConnectionInterface $conn
* #param string $id The unique ID of the RPC, required to respond to
* #param string|Topic $topic The topic to execute the call against
* #param array $params Call parameters received from the client
*/
function onCall(ConnectionInterface $conn, $id, $topic, array $params)
{
// TODO: Implement onCall() method.
}
/**
* A client is attempting to publish content to a subscribed connections on a URI
* #param \Ratchet\ConnectionInterface $conn
* #param string|Topic $topic The topic the user has attempted to publish to
* #param string $event Payload of the publish
* #param array $exclude A list of session IDs the message should be excluded from (blacklist)
* #param array $eligible A list of session Ids the message should be send to (whitelist)
*/
function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible)
{
// TODO: Implement onPublish() method.
}
}
There is another script that calls :
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send("okay");
die("okay");
First I run the client code in a browser(note, its the same machine as server):
<script src="http://autobahn.s3.amazonaws.com/js/autobahn.min.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>
this connection works, as I am able to see the log message in my server console output.
However, when I call the script that is supposed to send data to the client, the client does not receive it. No log messages are produced in client browser.
To explain why your configuration was not working.
You are sending the message "okay" to the pushserver from the piece of code you have
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send("okay"); -- HERE --
die("okay");
and in this piece of code you receive that call, this method expects you to send the $entryData['category'] as the 'channel' you want to send the data to
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
// 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);
}
Although the client is connected to the kittensCategory
conn.subscribe('kittensCategory', function(topic, data){
What you actually should do is send a correct object to the pushserver so that the websocket would know where to send the data to.
$entryData = array(
'category' => 'kittensCategory',
'data' => 'hello'
);
this code would send your data to the kittensCategory
If you need more information please let me know
After trying this for a few hours, I read somewhere to enable debug using ab.debug(true,true).
After that, I see that messages are indeed getting received.
Related
I am trying to follow this tutorial for Ratchet/ZMQ Socket programming:
http://socketo.me/docs/push
with a bit of customisation to learn abit more about it.
The server itself is running fine and the connection between front-end html seems to be connecting right. But I cant figure the PHP file that sends a message to the server.
CODES BELOW:
SENDER.PHP
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH,'my pusher');
$socket->connect('tcp://127.0.0.1:5555');
$socket->send("SENDING A MESSAGE");
The code above is what Im having problems with. When I run the code in the command line
php sender.php
The server should at least display some feed back but it doesnt give me anything. And the sender.php just exits.
Im stuck trying to figure out what Im missing. At least the front-html bit works.
How can I get the sender.php to send the message? Any suggestion/advise/help would be greatly appreciated.
Below are the rest of my codes:
INDEX.html
This html file is connecting as Im getting the message from the constructor.
ab.debug(true,true);
var conn = new ab.Session('ws://localhost:8080',
function() {
conn.subscribe('kittensCategory', function(data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
console.log("New data available: ",data);
});
},
function() {
console.warn('WebSocket connection closed');
},
{'skipSubprotocolCheck': true}
);
SERVER.PHP
use Models\SCSTRealtimeSubsObject;
// The event loop that will keep on triggering
$loop = React\EventLoop\Factory::create();
// Our custom pusher that will do the logic, $loop is optional
$pusher = new SCSTRealtimeSubsObject;
// 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);
//Binding to itself means the client can only connect to itself
$pull->bind("tcp://127.0.0.1:5555");
//On a 'message' event, pass the data to the myMessageHandler method of the MyPusherClass
$pull->on('message', array($pusher, 'customAction'));
// 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();
PUSHER.PHP
class SCSTRealtimeSubsObject implements WampServerInterface {
public function __construct() {
echo "Constructor call. \n";
}
public function customAction($msg){ // Message from the onMessage
echo "There was a message: $msg";
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// WampServerInterface Implementations
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
public function onOpen(ConnectionInterface $conn) {
echo "New connection! ({$conn->resourceId}) \n";
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it, as we can no longer send it messages
echo "Connection {$conn->resourceId} has disconnected \n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "There is an error ". $e->getMessage();
}
public function onSubscribe(ConnectionInterface $conn, $topic) {
echo "New subscriber : $topic \n";
}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
echo "Unsubscribed : $topic \n";
}
public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
// In this application if clients send data it's because the user hacked around in console
$conn->callError($id, $topic, 'You are not allowed to make calls')->close();
}
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
// In this application if clients send data it's because the user hacked around in console
echo "Published $topic. \n";
$conn->close();
}
}
Finally found the answer. I forgot to enclosed that my development server is on Windows.
In my case, php cli is firewalled by windows and is blocked from accessing any networks and ports.
To fix this go to control panel -> windows firewall. Look for inbound CLI this is most likely the PhP exe. Allow access to network and that should do the trick.
I try build real-time application with RatchetPHP and ZeroMQ. When my clients subscribes to my WebSocket, I would want push some data to my Master. But not every request is pushed to my Master. If More specifically, every second request is pushed. When I run my script, and reload connection to websocket several times I ses following output:
Topic manager started!
Master started!
Opened connection!
Master: message handled by :NULL
Opened connection!
Opened connection!
Master: message handled by :NULL
Opened connection!
Opened connection!
Master: message handled by :NULL
Opened connection!
Opened connection!
Master: message handled by :NULL
Opened connection!
It means, that when I connect to my Websocket, only second connection push data to Master. And my code is below:
use React\EventLoop\LoopInterface;
use React\ZMQ\Context;
class Master
{
const MASTER_PORT = 3333;
public function __construct(LoopInterface $loop) {
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new Context($loop);
$pull = $context->getSocket(\ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:' . self::MASTER_PORT); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($this, 'onMessage'));
echo 'Master started!' . PHP_EOL;
}
public function onMessage($message) {
echo 'Master: message handled :';
var_dump($message);
}
// ...
}
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
use Ratchet\WebSocket\WsServerInterface;
class Pusher implements WsServerInterface, WampServerInterface {
const WEBSOCKET_PORT = 5555;
/**
* #var Topic[]
*/
protected $topicLookup = array();
protected $pushMaster;
public function __construct()
{
// Push to master
$context = new \ZMQContext();
$this->pushMaster = $context->getSocket(\ZMQ::SOCKET_PUSH, 'workers');
$this->pushMaster->connect("tcp://localhost:" . Master::MASTER_PORT);
echo 'Topic manager started!' . PHP_EOL;
}
/**
* {#inheritdoc}
*/
public function onOpen(ConnectionInterface $conn) {
$conn->WAMP->subscriptions = new \SplObjectStorage;
echo 'Opened connection!' . PHP_EOL;
}
/**
* {#inheritdoc}
*/
public function onSubscribe(ConnectionInterface $conn, $topic) {
echo 'Subscribe for ' . $topic . PHP_EOL;
$topicObj = $this->getTopic($topic);
if ($conn->WAMP->subscriptions->contains($topicObj)) {
return;
}
$this->topicLookup[$topic]->add($conn);
$conn->WAMP->subscriptions->attach($topicObj);
}
protected function getTopic($topic) {
if (!array_key_exists($topic, $this->topicLookup)) {
echo $topic . ' before send' . PHP_EOL;
$this->push(json_encode(['action' => 'start', 'from' => $topic]));
$this->topicLookup[$topic] = new Topic($topic);
}
return $this->topicLookup[$topic];
}
/**
* #param string JSON'ified string we'll receive from ZeroMQ
*/
public function onPush($entry) {
$entryData = json_decode($entry, true);
// If the lookup topic object isn't set there is no one to publish to
if (!array_key_exists($entryData['symbol'], $this->topicLookup)) {
return;
}
$topic = $this->topicLookup[$entryData['symbol']];
// re-send the data to all the clients subscribed to that category
$topic->broadcast($entryData);
}
}
// script
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new \app\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:' . \app\socket\Pusher::WEBSOCKET_PORT); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onPush'));
// Start master for listening messages from Pusher
//$master = new \app\daemon\Master($loop);
// 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\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new \app\socket\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
What I do wrong?
I have successfully integrated the Ratchet chat unto my Laravel app, now I want to integrate the Ratchet push integration but sadly not working. First I have this pusher.php server file on the root directory of my Laravel app project folder
<?php
use App\Http\Controllers\SocketController;
require './vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$pusher = new SocketController();
// 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($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
);
echo "Pusher server is running\n";
$loop->run();
and this controller named SocketController.php
<?php
namespace App\Http\Controllers;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\Topic;
use Ratchet\Wamp\WampServerInterface;
class SocketController implements WampServerInterface
{
/**
* A lookup of all the topics clients have subscribed to
*/
protected $subscribedTopics = array();
public function onSubscribe(ConnectionInterface $conn, $topic) {
echo"on";
$this->subscribedTopics[$topic->getId()] = $topic;
}
/**
* #param string JSON'ified string we'll receive from ZeroMQ
*/
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
// 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);
echo "A new topic has been push";
}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
echo "A client has subscribed ".$conn->resourceId."\n";
}
public function onOpen(ConnectionInterface $conn) {
echo "A client is connected ".$conn->resourceId."\n";
}
public function onClose(ConnectionInterface $conn) {
echo "A client has been disconnected ".$conn->resourceId."\n";
}
/* The rest of our methods were as they were, omitted from docs to save space */
/**
* If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
* the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
* #param ConnectionInterface $conn
* #param \Exception $e
* #throws \Exception
*/
function onError(ConnectionInterface $conn, \Exception $e)
{
// TODO: Implement onError() method.
}
/**
* An RPC call has been received
* #param \Ratchet\ConnectionInterface $conn
* #param string $id The unique ID of the RPC, required to respond to
* #param string|Topic $topic The topic to execute the call against
* #param array $params Call parameters received from the client
*/
function onCall(ConnectionInterface $conn, $id, $topic, array $params)
{
// TODO: Implement onCall() method.
}
/**
* A client is attempting to publish content to a subscribed connections on a URI
* #param \Ratchet\ConnectionInterface $conn
* #param string|Topic $topic The topic the user has attempted to publish to
* #param string $event Payload of the publish
* #param array $exclude A list of session IDs the message should be excluded from (blacklist)
* #param array $eligible A list of session Ids the message should be send to (whitelist)
*/
function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible)
{
// TODO: Implement onPublish() method.
}
}
Yes, I followed everything from http://socketo.me/docs/push. Next, I set up a route and a test controller to be used for pushing an entry.
In the route
Route::get('/test','testController#index');
the test controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use \ZMQContext;
use \ZMQ;
class testController extends Controller
{
public function index(){
$entryData = array(
'category' => 'cat',
'title' => 'title 1',
'article' => 'article 1',
'when' => time()
);
// This is our new stuff
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://localhost:5555");
$socket->send(json_encode($entryData));
dd($entryData);
}
}
and in the client side, I'll connect it to the Ratchet push server.
<script src="http://autobahn.s3.amazonaws.com/js/autobahn.min.js"></script>
<script>
var conn = new ab.Session('ws://localhost:8080',
function() {
conn.subscribe('cat', function(topic, data) {
// This is where you would add the new article to the DOM (beyond the scope of this tutorial)
alert('New article published to category "' + topic + '" : ' + data.title);
});
},
function() {
console.warn('WebSocket connection closed');
},
{'skipSubprotocolCheck': true}
);
</script>
Now, I run the pusher.php by
cd c:/wamp/www/laravelApp php pusher.php
and in the console, I did log that the client side is connected but when I visit localhost:8000/test from my browser (push entry), it did not the
echo "A new topic has been push";
as it supposed to because I set it up here
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
// 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);
echo "A new topic has been push";
}
so it means, subscribing to a category is not working, any ideas, help please?
Brief Explanation...
I am trying to set up a Ratchet Web Socket server and am having a few issues. Here is what I am trying to achieve:
I have a counter on my website that indicates how many users have signed up to the website. I would like this counter to update whenever another users signs up to the website. Simples...
What I have Tried
I have only been using Ratchet for around 24 hours so my experience is extremely limited to say the least, but nevertheless, I have read the documentation thoroughly and I believe I am on the right track.
Here is my code:
push-server.php
// Autoload any required libraries
require(dirname(__DIR__).'/vendor/autoload.php');
// Initiate the loop and pusher
$loop = React\EventLoop\Factory::create();
$pusher = new _sockets\pusher;
// Listen for the web server to make a ZeroMQ push
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
// Binding to 127.0.0.1 means the only client that can connect is itself
$pull->bind('tcp://127.0.0.1:5555');
$pull->on('message', array($pusher,'message'));
// Set up the web socket server for the clients
$web_socket = new React\Socket\Server($loop);
// Binding to 0.0.0.0 means remotes can connect
$web_socket->listen(8080,'0.0.0.0');
$web_server = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$web_socket
);
// Run the loop
$loop->run();
pusher.php
namespace _sockets;
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) {
$this->subscribedTopics[$topic->getId()] = $topic;
}
public function onUnSubscribe(ConnectionInterface $conn, $topic){
}
public function onOpen(ConnectionInterface $conn){
}
public function onClose(ConnectionInterface $conn){
}
public function onCall(ConnectionInterface $conn, $id, $topic, array $params){
}
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible){
}
public function onError(ConnectionInterface $conn, \Exception $e){
}
public function message($data){
$data = json_decode($data,true);
// If the lookup topic object isn't set there is no one to publish to
if(!array_key_exists($data['category'],$this->subscribedTopics)) {
return;
}
$topic = $this->subscribedTopics[$data['category']];
// re-send the data to all the clients subscribed to that category
$topic->broadcast($data);
}
}
Snippet from Sign Up Script
// Push the sign up notice to all connections
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH);
$socket->connect("tcp://localhost:5555");
$array = array(
'category' => 'user_signed_up'
);
$socket->send(json_encode($array));
Snippet from JavaScript
// Connect to the website
var connection = new ab.Session('ws://MY_IP_ADDRESS:8080',
function(){
console.log('Connected to WebSocket');
connection.subscribe('user_signed_up',function(topic,data){
console.log(topic,data);
});
},
function(){
console.log('WebSocket Connection Closed');
},
{
'skipSubprotocolCheck': true
}
);
My Questions
All of the above works but before I proceed to thorough testing and production, I have a couple of questions:
Is the $persistent_id necessary with the getSocket method? I have read documentation but what is it actually used for? Do I need it, or, should I be using it?
I have been unable to find documentation on the on method for the ZMQ\Context class, has this been deprecated? Should I be using this or instead should I use recv?
How can I ensure my push-server.php is running all the time? Is there some sort of daemon tool I can use to ensure it is always running and will auto start if the server is rebooted?
Is it possible to attach the websocket to my domain instead of my IP Address? When I use my domain within the JavaScript, I receive a 400 Error...
I'm creating a Twitter client, and I need to handle the tweets coming from each streaming processes (started with Symfony's Process component). I have a websocket server running in the background which works perfectly.
My problem is that I don't know how should I get the data streamed from these processes and pass back to the client through the socket. To keep checking an read the the output I need to create a while loop for it, but that will prevent other users to start their stream, because the socket server will stuck at that loop.
If possible, I want to avoid the using of DB queues.
The server, started from terminal:
class StreamServer extends \WebSocketServer
{
/**
*
* Called immediately when the data is recieved.
*
* #param $user
* #param $message
*/
protected function process($user, $message)
{
var_dump($user);
}
/**
* Called after the handshake response is sent to the client.
*
* #param $user
*/
protected function connected($user)
{
$streamer = new Process('php Streamer.php');
$streamer->setTimeout(null);
$streamer->start();
$this->send($user, 'tweets');
}
/**
* Called after the connection is closed.
*
* #param $user
*/
protected function closed($user)
{
$this->disconnect($user->socket);
}
}
$echo = new StreamServer("127.0.0.1", "9000");
try {
$echo->run();
} catch (Exception $e) {
$echo->stdout($e->getMessage());
}
Streamer:
class Streamer
{
public function run()
{
// $this->user = $user;
echo 'hello';
$config = [
'oauth' => [
'consumer_key' => '**',
'consumer_secret' => '**',
'token' => '**',
'token_secret' => '**',
],
];
$floodgate = Floodgate::create($config);
$handler = function ($message)
{
var_export($message);
};
$generator = function ()
{
return [];
};
$floodgate->user($handler, $generator);
}
}
$stream = new Streamer();
$stream->run();
I found a solution, called ReactPHP & Ratchet.