socket学习纪录3: workerman 向某个特定用户/客户端发送消息

蛰伏已久 蛰伏已久 2018-05-29

我们要想实现向某个特定用户发送消息,必须要实现以下几点

  • 进程数为1

  • 设置每个connection的uid为用户id、token,或者其他唯一标识

  • 用一个数组存储每个用户对应的connection

实现思路

每个客户端在连接服务器后,上报自己的uid,比如发送给服务器的数据格式为,"type"为"login","uid"为用户id

var data = {
   type: 'login',
   uid: '456'
}

客户端发送消息时,"type"设为"send_message","to"代表发送给谁,"all",代表发送给所有人,否则为某个用户的id

var data = {
   type: 'send_message',
   to: '456',
   message: "456,你好啊"
}

服务端在接收到客户端消息后,对接收的消息进行处理,如果type为login,则保存connection的uid,如果type为"send_message",则发送数据。

代码实现

服务器端代码

<?php

//启动socket服务
require_once __DIR__ . '/Autoloader.php';
use Workerman\Worker;
use Workerman\Lib\Timer;




$ws_worker = new Worker("websocket://0.0.0.0:2347");


$ws_worker->count = 1;// 只启动1个进程

$ws_worker->connection_uids=array(); //保存每个用户的connection

$ws_worker->onMessage = function($connection, $data){
    global $ws_worker;

    $d=json_decode($data);

    switch($d->type){
        case 'login':
            $connection->uid=$d->uid;
            $ws_worker->connection_uids[$d->uid]=$connection;
            echo "收到登录请求,uid={$d->uid}\n";
            break;
        case 'send_message':
            if($d->to=='all'){
                echo "向全部用户发送消息\n";
                broadcast($d->message);
            }else{
                echo "向用户{$d->to}发送消息\n";
                sendMessageByUid($d->to,$d->message);
            }
            break;
        default:
            break;

    }

};

$ws_worker->onClose = function($connection){
    global $ws_worker;
    echo "用户{$connection->uid}退出\n";
    
    if(isset($connection->uid)){
        unset($ws_worker->connection_uids[$connection->uid]);
    }
};

//向所有用户发送消息
function broadcast($message){
    global $ws_worker;
    foreach($ws_worker->connections as $conn){
        $conn->send($message);
    }
}

//向某个用户发送消息
function sendMessageByUid($uid,$message){
    global $ws_worker;
    if(isset($ws_worker->connection_uids[$uid])){
        $conn=$ws_worker->connection_uids[$uid];
        $conn->send($message);
    }
}

Worker::runAll();

小程序1 核心代码

wx.onSocketOpen(function (res) {
console.log('WebSocket连接已打开!')

var data1={
type:'login',
uid:'123'
}
wx.sendSocketMessage({
data: JSON.stringify(data1),
})

var data2 = {
type: 'send_message',
to: 'all',
message:"大家好"
}

setInterval(function(){
wx.sendSocketMessage({
data: JSON.stringify(data2),
})
},8000)

})

小程序2核心代码

wx.onSocketOpen(function (res) {
console.log('WebSocket连接已打开!')
var data1 = {
type: 'login',
uid: '456'
}
wx.sendSocketMessage({
data: JSON.stringify(data1),
})

var data2 = {
type: 'send_message',
to: '123',
message: "123,你好吗"
}
setInterval(function () {
wx.sendSocketMessage({
data: JSON.stringify(data2),
})
}, 8000)
})



分享到

点赞(9)