用webman+AI寫了聊天室的代碼,服務端一直收不到消息,哪里的問題???
<?php
namespace app\process;
use support\Log;
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Timer;
class ChatServer
{
protected static $connections = [];
protected static $connectionMap = []; // 新增:IP到連接的映射
public function onWorkerStart()
{
// 創(chuàng)建 WebSocket 服務器
Log::channel('timer')->info("WebSocket 服務器啟動", ['port' => '8788']);
$ws_worker = new Worker('websocket://0.0.0.0:8788');
$ws_worker->name='tt';
//$ws_worker->count = 3;
// 心跳設置
define('HEARTBEAT_INTERVAL', 25);
// 連接建立
$ws_worker->onConnect = function (TcpConnection $connection) {
$ip = $connection->getRemoteIp();
$port = $connection->getRemotePort();
$connectionId = "$ip:$port";
// 存儲連接
self::$connections[$connection->id] = $connection;
self::$connectionMap[$connectionId] = $connection->id;
$connection->lastMessageTime = time();
$connection->send(json_encode([
'type' => 'system',
'message' => '歡迎加入聊天室!請設置昵稱',
'time' => date('H:i')
]));
Log::channel('timer')->info("system", ['broadcast' => [
'type' => 'system',
'message' => '歡迎加入聊天室!請設置昵稱',
'time' => date('H:i')
]]);
};
// 收到消息
$ws_worker->onMessage = function (TcpConnection $connection, $data) {
$connection->send("hello");
Log::channel('timer')->info("收到消息", ['connection_id' => $connection->id,'raw_data' => $data]);
$connection->lastMessageTime = time();
$message = json_decode($data, true);
// 處理消息類型
switch ($message['type'] ?? '') {
case 'join':
// 用戶加入
$connection->username = $message['username'];
self::$connections[$connection->id] = $connection;
// 廣播用戶加入
$this->broadcast([
'type' => 'system',
'message' => "{$message['username']} 加入了聊天室",
'time' => date('H:i')
], $connection->id);
break;
case 'chat':
// 聊天消息
if (!isset($connection->username)) {
$connection->send(json_encode([
'type' => 'system',
'message' => '請先設置昵稱',
'time' => date('H:i')
]));
return;
}
// 構建完整的消息
$broadcastMessage = [
'type' => 'chat',
'username' => $connection->username,
'message' => $message['message'],
'time' => date('H:i')
];
$this->broadcast($broadcastMessage);
break;
}
// Worker::runAll();
};
// 連接關閉
$ws_worker->onClose = function (TcpConnection $connection) {
$ip = $connection->getRemoteIp();
$port = $connection->getRemotePort();
$connectionId = "$ip:$port";
if (isset($connection->username)) {
// 廣播用戶離開
$this->broadcast([
'type' => 'system',
'message' => "{$connection->username} 離開了聊天室",
'time' => date('H:i')
]);
}
// 從連接池移除
unset(self::$connections[$connection->id]);
unset(self::$connectionMap[$connectionId]);
};
// 心跳檢測
Timer::add(10, function() use ($ws_worker) {
$now = time();
foreach ($ws_worker->connections as $connection) {
if ($now - $connection->lastMessageTime > HEARTBEAT_INTERVAL) {
$connection->close();
}
}
});
Log::channel('timer')->info("WebSocket方法end", ['end' => date('YmdHi')]);
}
// 廣播消息給所有客戶端
private function broadcast(array $message, $excludeId = null)
{
// 確保消息包含所有必要字段
if ($message['type'] == 'chat') {
$message = array_merge([
'username' => '系統(tǒng)',
'time' => date('H:i')
], $message);
}
// 確保系統(tǒng)消息也有時間
if ($message['type'] == 'system' && !isset($message['time'])) {
$message['time'] = date('H:i');
}
$json = json_encode($message);
Log::channel('timer')->info("broadcast", ['broadcast' => $message]);
foreach (self::$connections as $id => $connection) {
// 排除特定連接
if ($excludeId !== null && $id === $excludeId) continue;
try {
$connection->send($json);
} catch (\Exception $e) {
// 忽略發(fā)送失敗
}
}
}
}