// 标记是全局启动 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();