// 標記是全局啓動 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();