webman icon indicating copy to clipboard operation
webman copied to clipboard

Simple Websocket for realtime data

Open haidarvm opened this issue 2 years ago • 10 comments

I want to build realtime data recieve it from Pyhton script that connected with Raspberry

I did follow this step: http://doc.workerman.net/worker/listen.html

but I cannot modify those script, it only start with uid1

so, how can i do for dynamic data ?

and can it send via url to send to websocket?

example http://localhost:8000/?id=1&data=51

haidarvm avatar Oct 19 '21 11:10 haidarvm

Here is an example.

<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
global $worker;
$worker = new Worker('websocket://0.0.0.0:1234');
// count mast be 1
$worker->count = 1;
$worker->onWorkerStart = function($worker)
{
    $inner_text_worker = new Worker('http://0.0.0.0:5678');
    $inner_text_worker->onMessage = function($connection, $request) {
        global $worker;
        $uid = $request->get('id');
        $data = $request->get('data');
        $ret = sendMessageByUid($uid, $data);
        $connection->send($ret ? 'ok' : 'fail');
    };
    $inner_text_worker->listen();
};
$worker->uidConnections = array();
$worker->onMessage = function($connection, $data)use($worker)
{
    // $data = '["uid": "xxx"]';
    if(!isset($connection->uid)) {
        $data = json_decode($data, true);
        if (!isset($data['uid'])) return;
        $connection->uid = $data['uid'];
        $worker->uidConnections[$connection->uid] = $connection;
        return;
    }
};

$worker->onClose = function($connection)use($worker)
{
    global $worker;
    if(isset($connection->uid)) {
        unset($worker->uidConnections[$connection->uid]);
    }
};

function broadcast($message)
{
    global $worker;
    foreach($worker->uidConnections as $connection) {
        $connection->send($message);
    }
}

function sendMessageByUid($uid, $message)
{
    global $worker;
    if(isset($worker->uidConnections[$uid]))
    {
        $connection = $worker->uidConnections[$uid];
        $connection->send($message);
        return true;
    }
    return false;
}
Worker::runAll();

Javascript

// Change the uid value according to the current user. Let's assume that uid is 123
uid = 123;
ws = new WebSocket('ws://127.0.0.1:1234');
ws.onopen = function(){
    ws.send(JSON.stringify({uid:uid}));
};
ws.onmessage = function(e){
    console.log(e.data);
};

When you visit http://127.0.0.1:5678/?id=123&data=bla

The results image

walkor avatar Oct 19 '21 11:10 walkor

Ok thats great, it works

but still how to modify to get all uid not only 123

so it can receive any uid 123, 234 or 12 ?

haidarvm avatar Oct 19 '21 12:10 haidarvm

I don't understand what you're talking about. You can modify it yourself if necessary

walkor avatar Oct 19 '21 12:10 walkor

I mean if i put this on url http://127.0.0.1:5678/?id=23&data=haidar it said fail

haidarvm avatar Oct 19 '21 12:10 haidarvm

That means uid 23 not online.

walkor avatar Oct 19 '21 12:10 walkor

Ok but can i add more parameter on the url, for example :

http://127.0.0.1:5678/?id=123&data=result&progress=88%

haidarvm avatar Oct 19 '21 14:10 haidarvm

Yes you can.

walkor avatar Oct 20 '21 01:10 walkor

Hi walkor, I just checked if it run on multiple browser than the first client browser stop received data websocket. So how to update all client browser ?

haidarvm avatar Nov 01 '21 09:11 haidarvm

<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
global $worker;
$worker = new Worker('websocket://0.0.0.0:1234');
// count mast be 1
$worker->count = 1;
$worker->onWorkerStart = function($worker)
{
    $inner_text_worker = new Worker('http://0.0.0.0:5678');
    $inner_text_worker->onMessage = function($connection, $request) {
        global $worker;
        $uid = $request->get('id');
        $data = $request->get('data');
        $ret = sendMessageByUid($uid, $data);
        $connection->send($ret ? 'ok' : 'fail');
    };
    $inner_text_worker->listen();
};
$worker->uidConnections = array();
$worker->onMessage = function($connection, $data)use($worker)
{
    // $data = '["uid": "xxx"]';
    if(!isset($connection->uid)) {
        $data = json_decode($data, true);
        if (!isset($data['uid'])) return;
        $connection->uid = $data['uid'];
        $worker->uidConnections[$connection->uid][$connection->id] = $connection;
        return;
    }
};

$worker->onClose = function($connection)use($worker)
{
    global $worker;
    if(isset($connection->uid)) {
        unset($worker->uidConnections[$connection->uid][$connection->id]);
        if (empty($worker->uidConnections[$connection->uid])) {
            unset($worker->uidConnections[$connection->uid]);
        }
    }
};

function broadcast($message)
{
    global $worker;
    foreach($worker->uidConnections as $connections) {
        foreach ($connections as $connection) {
            $connection->send($message);
        }
    }
}

function sendMessageByUid($uid, $message)
{
    global $worker;
    if(isset($worker->uidConnections[$uid]))
    {
        $connections = $worker->uidConnections[$uid];
        foreach ($connections as $connection) {
            $connection->send($message);
        }
        return true;
    }
    return false;
}
Worker::runAll();

walkor avatar Nov 01 '21 09:11 walkor

Great, Its works

haidarvm avatar Nov 01 '21 09:11 haidarvm