Ejemplo 1
(requiere Workerman versión >= 3.3.0)
Sistema de push grupal multihilo basado en Worker
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$channel_server = new Channel\Server('0.0.0.0', 2206);
$worker = new Worker('websocket://0.0.0.0:1234');
$worker->count = 8;
// Mapa de conexión de grupo a conexión
$group_con_map = array();
$worker->onWorkerStart = function(){
// El cliente de Channel se conecta al servidor de Channel
Channel\Client::connect('127.0.0.1', 2206);
// Escuchar el evento de envío de mensajes a grupos globales
Channel\Client::on('send_to_group', function($event_data){
$group_id = $event_data['group_id'];
$message = $event_data['message'];
global $group_con_map;
var_dump(array_keys($group_con_map));
if (isset($group_con_map[$group_id])) {
foreach ($group_con_map[$group_id] as $con) {
$con->send($message);
}
}
});
};
$worker->onMessage = function(TcpConnection $con, $data){
// Mensaje para unirse al grupo {"cmd":"add_group", "group_id":"123"}
// O mensaje masivo {"cmd":"send_to_group", "group_id":"123", "message":"este es el mensaje"}
$data = json_decode($data, true);
var_dump($data);
$cmd = $data['cmd'];
$group_id = $data['group_id'];
switch($cmd) {
// Conexión para unirse al grupo
case "add_group":
global $group_con_map;
// Agregar conexión al array del grupo correspondiente
$group_con_map[$group_id][$con->id] = $con;
// Registrar en qué grupos se unió esta conexión, para poder limpiar datos en onclose
$con->group_id = isset($con->group_id) ? $con->group_id : array();
$con->group_id[$group_id] = $group_id;
break;
// Enviar mensaje masivo al grupo
case "send_to_group":
// Channel\Client difunde el evento de envío de mensajes masivos a todos los procesos del servidor
Channel\Client::publish('send_to_group', array(
'group_id'=>$group_id,
'message'=>$data['message']
));
break;
}
};
// Esto es muy importante, eliminar la conexión del mapa de datos global del grupo al cerrar la conexión para evitar pérdidas de memoria
$worker->onClose = function(TcpConnection $con){
global $group_con_map;
// Recorrer todos los grupos a los que se unió la conexión y eliminar los datos correspondientes del group_con_map
if (isset($con->group_id)) {
foreach ($con->group_id as $group_id) {
unset($group_con_map[$group_id][$con->id]);
if (empty($group_con_map[$group_id])) {
unset($group_con_map[$group_id]);
}
}
}
};
Worker::runAll();
Prueba (asumiendo que todo se ejecuta en la misma máquina 127.0.0.1)
- Ejecutar el servidor
php start.php start Workerman[del.php] start in DEBUG mode ----------------------- WORKERMAN ----------------------------- Workerman version:3.4.2 PHP version:7.1.3 ------------------------ WORKERS ------------------------------- user worker listen processes status liliang ChannelServer frame://0.0.0.0:2206 1 [OK] liliang none websocket://0.0.0.0:1234 12 [OK] ---------------------------------------------------------------- Presiona Ctrl-C para salir. Inicio exitoso.
2. El cliente se conecta al servidor
Abre el navegador Chrome, presiona F12 para abrir la consola de depuración, en la pestaña Console ingresa (o coloca el siguiente código en una página html para que se ejecute con js)
```javascript
// Supongamos que la IP del servidor es 127.0.0.1, por favor cambia a la IP real del servidor para las pruebas
ws = new WebSocket('ws://127.0.0.1:1234');
ws.onmessage = function(data){console.log(data.data)};
ws.onopen = function() {
ws.send('{"cmd":"add_group", "group_id":"123"}');
ws.send('{"cmd":"send_to_group", "group_id":"123", "message":"este es el mensaje"}');
};