howey
// 标记是全局启动
define(\'GLOBAL_START\', 1);

require_once __DIR__ . \'/Workerman/Connection.php\';
require_once __DIR__ . \'/Workerman/Autoloader.php\';

use Workerman\Worker;
use Workerman\Lib\Timer;

// 心跳间隔25秒
define(\'HEARTBEAT_TIME\', 25);

// 设置时区
date_default_timezone_set(\'PRC\');

// 以websocket协议为例
// Create a Websocket server
$ws = new Worker("websocket://118.xxx.xxx.xx:4980");

// 启动4个进程对外提供服务
$ws->count = 4;

// 已连接客户端 ,便于统计在线用户
$ws->hasConnections = array();

// 当新客户端连上来时分配uid,并保存连接,并通知所有客户端
$ws->onConnect = function($connection)
{
    global $ws;
    // 为这个链接分配一个uid
    $connection->uid = ++$global_uid;

    foreach ($ws->connections as $conn) {
        $conn->send("用户{$connection->uid} 已上线");
    }
    $connection->close(); // 关闭socket连接
    // echo "New connection\n";
 };

// 当客户端发送消息过来时,转发给所有人 (聊天主要使用的功能)
$ws->onMessage = function($connection, $message)
{
    global $ws,$db;
    $data = json_decode($message, true);

    $data[\'time\'] = date(\'Y-m-d H:i:s\');
    $insert = array(
        \'uid\'         =>$data[\'uid\'],
        \'avatar\'      =>$data[\'avatar\'],
        \'name\'        =>$data[\'name\'],
        \'type\'        =>$data[\'type\'],
        \'content\'     =>$data[\'content\'],
        \'img_path\'    =>$data[\'img_path\'],
        \'voice_path\'  =>$data[\'voice_path\'],
        \'topic_id\'    =>$data[\'topic_id\'],
        \'is_question\' =>$data[\'is_question\'],
        \'status\'      =>$data[\'status\'],
        \'time\'        =>$data[\'time\']
    );

    switch ($data[\'type\']) {
        case \'save\':
            // 把房间和用户信息保存下来
            $ws->hasConnections[$connection->id] = array(\'name\' => $data[\'name\'], \'uid\' => $data[\'uid\'], \'topic_id\' => $data[\'topic_id\'], \'avatar\' => $data[\'avatar\']);
            sendMessage($data, $data[\'topic_id\']);
            // $back_data = array(\'content\' => $content, \'client_id\' => $connection->id, \'client_name\' => $data[\'name\'], \'type\' => \'login\', \'clients\' => $ws->hasConnections, \'time\' => date(\'Y-m-d H:i:s\'));

            break;

        case \'text\':
            sendMessage($data, $data[\'topic_id\']);
            $insert_id = $db->insert(\'chat_record\')->cols($insert)->query();  // 存数据库 save data
            break;

        case \'img\':
            sendMessage($data, $data[\'topic_id\']);
            $insert_id = $db->insert(\'chat_record\')->cols($insert)->query();  // 存数据库 save data
            break;

        case \'voice\':
            sendMessage($data, $data[\'topic_id\']);
            $insert_id = $db->insert(\'chat_record\')->cols($insert)->query();  // 存数据库 save data
            break;
        default:
            break;
    }

    // $connection->close(); // 关闭socket连接
};

// 当客户端断开时,广播给所有客户端
// $ws->onClose = function($connection)
// {
//     global $ws;
//     foreach ($ws->connections as $conn) {
//         $conn->send("用户[{$connection->uid}] 消消走了");
//     }
//     $connection->close(); // 关闭socket连接
// };

// 给房间的每个人发消息
function sendMessage($data, $topic_id){
    global $ws;
    $data = json_encode($data);
    foreach ($ws->connections as $id => $conn) {
        if ($ws->hasConnections[$id][\'topic_id\'] == $topic_id) {
            $conn->send($data);
            // $conn->send($ws->hasConnections[$id]);
        }
    }
}

// 进程启动后设置一个每秒运行一次的定时器(心跳, 保持长连接)
$ws->onWorkerStart = function($ws) {
    global $db;
    // ip, 端口号, 账号, 密码, 库名
    $db = new \Workerman\MySQL\Connection(\'127.0.0.1\', \'3306\', \'username\', \'password\', \'database\');

    Timer::add(1, function()use($ws){
    // global $ws;
        $arr = array(\'type\'=>\'keep\',\'content\'=>\'ping\');
        $arr = json_encode($arr);
        foreach($ws->connections as $connection) {
            $connection->send($arr);
        }
    });
};


// Run worker
Worker::runAll();

 

分类:

技术点:

相关文章:

  • 2021-11-07
  • 2021-11-28
  • 2021-05-30
  • 2021-11-07
猜你喜欢
  • 2021-11-04
  • 2021-11-21
  • 2021-11-21
  • 2021-11-21
  • 2021-11-15
  • 2021-04-21
  • 2021-09-19
相关资源
相似解决方案