workerman icon indicating copy to clipboard operation
workerman copied to clipboard

How does the worker use the obtained ID to send a message to the specified customer?

Open micromotores opened this issue 2 years ago • 6 comments

How does the worker use the obtained ID to send a message to the specified customer?

micromotores avatar Jan 11 '22 14:01 micromotores

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.

walkor avatar Jan 12 '22 01:01 walkor

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{

        }
    };
```

`

micromotores avatar Jan 12 '22 11:01 micromotores

Just change. $worker = new Worker('websocket://0.0.0.0:5000'); to $worker = new Worker('tcp://0.0.0.0:5000');

walkor avatar Jan 12 '22 12:01 walkor

it shows me the following error when running the server: Error: multi workers init in one php file are not support

micromotores avatar Jan 12 '22 12:01 micromotores

Please use Linux system.

walkor avatar Jan 12 '22 12:01 walkor

ok thanks

micromotores avatar Jan 12 '22 12:01 micromotores