workerman
workerman copied to clipboard
How does the worker use the obtained ID to send a message to the specified customer?
How does the worker use the obtained ID to send a message to the specified customer?
Here is an example.
composer require workerman/channel
start.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
$channel_server = new Channel\Server('0.0.0.0', 2206);
$worker = new Worker('websocket://0.0.0.0:5000');
$worker->count = 4;
$group_con_map = array();
$worker->onWorkerStart = function(){
Channel\Client::connect('127.0.0.1', 2206);
Channel\Client::on('publish', function($event_data){
$subject = $event_data['subject'];
$message = $event_data['message'];
global $group_con_map;
if (isset($group_con_map[$subject])) {
foreach ($group_con_map[$subject] as $con) {
$con->send($message);
}
}
});
};
$worker->onMessage = function($con, $data){
// ["subscribe", "subject"]
// or ["publish", "subject", "This is a messsage"]
$data = json_decode($data, true);
$cmd = $data[0];
$subject = $data[1];
switch($cmd) {
case "subscribe":
global $group_con_map;
$group_con_map[$subject][$con->id] = $con;
$con->subjects = isset($con->subjects) ? $con->subjects : array();
$con->subjects[$subject] = $subject;
break;
case "publish":
$message = $data[2];
Channel\Client::publish('publish', array(
'subject'=>$subject,
'message'=>$message
));
break;
}
};
$worker->onClose = function($con){
global $group_con_map;
if (isset($con->subjects)) {
foreach ($con->subjects as $subject) {
unset($group_con_map[$subject][$con->id]);
if (empty($group_con_map[$subject])) {
unset($group_con_map[$subject]);
}
}
}
};
Worker::runAll();
js
ws = new WebSocket('ws://127.0.0.1:5000');
ws.onmessage = function(data){console.log(data.data)};
ws.onopen = function() {
ws.send('["subscribe", "user_id"]');
ws.send('["publish", "user_id", "This is a message"]');
};
Client for js side can subscribe any subject such as user_id by websocket. If any client want's to send data to any user_id in browser just call ws.send('["publish", "user_id", "This is a message"]');
In addition if you want to send data to any user in other php file. Just call like this.
<?php
require __DIR__ . '/vendor/autoload.php';
use Channel\Client;
Client::connect('127.0.0.1', 2206);
Channel\Client::publish('publish', array(
'subject' => 'user_id',
'message' => "This is a message too"
));
These codes can also be deployed distributed, greatly improving throughput.
this is my code , at the tcp level, how would it be? Thank you.
<?php
error_reporting(E_ERROR | E_PARSE);
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;// trabajador
use Workerman\Connection\TcpConnection;
use Workerman\Lib\Timer;// libreria tiempo
include "checksum.php";
include "changetimezone.php";
// Time out definicion de tiempo 600 para 6 minutos de espera
//20 min 1200 seg
$timeout=1200;
define('HEARTBEAT_TIME', $timeout);
define('ZONA_HORARIA_SERVER', 'GMT0');// define zona horaria servidor log en consola
// escuchando por la ip xx.xx.xx.xx:port
$worker = new Worker('tcp://0.0.0.0:10000');
$worker->name = 'Actuador y Tapas';
//nueva conexion
$worker->onConnect = function (TcpConnection $connection) {
date_default_timezone_set(ZONA_HORARIA_SERVER);
$fechayhoraview = date("Y-m-d H:i:s");
echo $connection->id;
echo "\033[01;36mNueva conexion desde:\033[0m\033[1;33m". $connection->getRemoteIp() . "||".$fechayhoraview."\n\033[0m";
$ipentrante=$connection->getRemoteIp();
if(($ipentrante == '164.90.184.159') or ($ipentrante == '162.142.125.195') or ($ipentrante == '167.248.133.59')){
echo "\033[01;36mConexion Peligrosa Cerrando:\033[0m\033[1;33m". $connection->getRemoteIp() . "\n\033[0m";
$connection->close();
}else{
}
};
```
`
Just change.
$worker = new Worker('websocket://0.0.0.0:5000');
to $worker = new Worker('tcp://0.0.0.0:5000');
it shows me the following error when running the server: Error: multi workers init in one php file are not support
Please use Linux system.
ok thanks