linux 上执行composer install 出现这个 undefined index:name 问题

本文讲述了在Linux环境下使用Composer安装时遇到'undefined index:name'错误的解决办法,通过降级Composer版本并重新安装来修复问题。

linux 上执行composer install 出现这个 undefined index:name 报错:

解决方案就是compoesr 版本降级

# composer 降级

composer self-update --1

# 再次安装,即可

composer install

#!/bin/bash # ======================================================== # WordPress + Workerman WebSocket IM 一键部署脚本 # 功能:自动创建插件、服务、Nginx代理、前端测试页 # 使用:chmod +x install-wp-im.sh && ./install-wp-im.sh --domain 域名 --site-root 网站根目录 # ======================================================== set -e # 出错即停止 # ============ 参数解析 ============ DOMAIN="" SITE_ROOT="" HELP=false while [[ "$#" -gt 0 ]]; do case $1 in --domain) DOMAIN="$2"; shift ;; --site-root) SITE_ROOT="$2"; shift ;; -h|--help) HELP=true; break ;; *) echo "未知参数: $1" >&2; exit 1 ;; esac shift done if [ "$HELP" = true ]; then echo "用法: $0 --domain <域名> --site-root <网站根目录>" echo "示例: $0 --domain yfw.szrengjing.com --site-root /www/wwwroot/yfw_szrengjing_com" exit 0 fi if [ -z "$DOMAIN" ] || [ -z "$SITE_ROOT" ]; then echo "错误: 必须指定 --domain 和 --site-root" echo "运行 $0 --help 查看帮助" exit 1 fi # ============ 变量定义 ============ PLUGIN_DIR="$SITE_ROOT/wp-content/plugins/wp-im-plugin" IM_SERVER="$PLUGIN_DIR/im-server.php" NGINX_CONF="/www/server/panel/vhost/nginx/${DOMAIN}.conf" SYSTEMD_SERVICE="/etc/systemd/system/wp-im-server.service" FRONTEND_TEST="$SITE_ROOT/websocket-test.html" LOG_DIR="/tmp" WORKER_USER="www" echo "🚀 开始部署 WebSocket IM 系统" echo "域名: $DOMAIN" echo "网站根目录: $SITE_ROOT" echo "插件路径: $PLUGIN_DIR" # ============ 1. 创建插件目录 ============ echo "📁 创建插件目录..." mkdir -p "$PLUGIN_DIR" # ============ 2. 生成 im-server.php (Workerman 服务) ============ cat > "$IM_SERVER" << 'EOF' <?php /** * Plugin Name: WP IM Plugin * Description: 基于 Workerman 的 WebSocket 实时通信服务 */ use Workerman\Worker; use Workerman\Lib\Timer; use Workerman\Connection\TcpConnection; require_once __DIR__ . '/Workerman/Autoloader.php'; // 初始化 worker $worker = new Worker('websocket://0.0.0.0:2121'); $worker->name = 'WP_IM_Server'; $worker->count = 1; // 单进程足够 $worker->user = 'www'; // 运行用户 // 存储所有连接的客户端 $connections = []; $worker->onWorkerStart = function () use (&$connections) { file_put_contents('/tmp/workerman_stdout.log', "IM Server started at " . date('Y-m-d H:i:s') . "\n", FILE_APPEND); }; $worker->onConnect = function (TcpConnection $conn) use (&$connections) { $conn->userId = null; $conn->userName = null; file_put_contents('/tmp/workerman_stdout.log', "新连接来自 {$conn->getRemoteIp()}:{$conn->getRemotePort()}\n", FILE_APPEND); }; $worker->onMessage = function (TcpConnection $conn, $data) use (&$connections, &$worker) { try { $msg = json_decode($data, true, 512, JSON_THROW_ON_ERROR); if ($msg['type'] === 'register') { $userId = $msg['userId'] ?? ''; $userName = htmlspecialchars($msg['userName'] ?? ''); // 验证是否为合法用户 ID(数字) if (!is_numeric($userId) || intval($userId) <= 0) { $conn->send(json_encode(['type' => 'error', 'message' => '非法用户ID'])); $conn->close(); return; } $conn->userId = $userId; $conn->userName = $userName; // 广播上线消息(除自己外) $online_msg = json_encode([ 'type' => 'user_online', 'userId' => $userId, 'userName' => $userName, 'time' => date('H:i') ]); foreach ($worker->connections as $c) { if ($c !== $conn) { $c->send($online_msg); } } // 欢迎自己 $conn->send(json_encode([ 'type' => 'welcome', 'message' => "欢迎回来,{$userName}" ])); file_put_contents('/tmp/workerman_stdout.log', "用户 {$userId}({$userName}) 上线\n", FILE_APPEND); } if ($msg['type'] === 'chat') { $content = htmlspecialchars($msg['content'] ?? ''); if (empty($content)) return; $fromName = $conn->userName ?: '匿名'; $fromId = $conn->userId ?: '0'; $chat_msg = json_encode([ 'type' => 'chat_message', 'fromUserId' => $fromId, 'fromUserName' => $fromName, 'content' => $content, 'time' => date('H:i') ]); // 广播给所有人(包括自己) foreach ($worker->connections as $c) { $c->send($chat_msg); } file_put_contents('/tmp/workerman_stdout.log', "聊天消息: [{$fromName}] {$content}\n", FILE_APPEND); } } catch (Exception $e) { file_put_contents('/tmp/workerman_stdout.log', "消息解析失败: {$e->getMessage()}\n", FILE_APPEND); } }; $worker->onClose = function (TcpConnection $conn) use (&$worker) { if ($conn->userId && $conn->userName) { $offline_msg = json_encode([ 'type' => 'user_offline', 'userId' => $conn->userId, 'userName' => $conn->userName, 'time' => date('H:i') ]); foreach ($worker->connections as $c) { if ($c !== $conn) { $c->send($offline_msg); } } file_put_contents('/tmp/workerman_stdout.log', "用户 {$conn->userId}({$conn->userName}) 下线\n", FILE_APPEND); } }; // 启动服务 if (basename(__FILE__) == 'im-server.php') { Worker::runAll(); } EOF echo "✅ 已生成 im-server.php" # ============ 3. 下载 Workerman 库 ============ echo "⏬ 下载 Workerman 依赖..." WORKERMAN_ZIP="/tmp/workerman.zip" curl -o "$WORKERMAN_ZIP" -L https://github.com/walkor/Workerman/archive/refs/tags/v4.1.16.zip unzip -qo "$WORKERMAN_ZIP" "Workerman-*/*" -d "$PLUGIN_DIR" mv "$PLUGIN_DIR"/Workerman-*/* "$PLUGIN_DIR/" rm -rf "$PLUGIN_DIR"/Workerman-*/ rm -f "$WORKERMAN_ZIP" echo "✅ Workerman 依赖已安装" # ============ 4. 生成 WordPress 插件主文件 ============ cat > "$PLUGIN_DIR/wp-im-plugin.php" << EOF <?php /** * Plugin Name: WP IM Plugin * Description: 实时聊天系统,集成 Workerman WebSocket * Version: 1.0 * Author: Admin */ // 阻止直接访问 if (!defined('ABSPATH')) exit; // 添加前端脚本钩子 function wp_im_enqueue_scripts() { wp_enqueue_script('wp-im-client', get_site_url() . '/websocket-test.html?js', array(), '1.0', true); } add_action('wp_enqueue_scripts', 'wp_im_enqueue_scripts'); // 提供给前端获取当前用户信息的接口 function wp_im_get_current_user_json() { if (is_user_logged_in()) { \$user = wp_get_current_user(); echo '<script>window.WP_IM_USER = {id: "' . esc_js(\$user->ID) . '", name: "' . esc_js(\$user->display_name) . '"};</script>'; } else { echo '<script>window.WP_IM_USER = null;</script>'; } } add_action('wp_head', 'wp_im_get_current_user_json'); EOF echo "✅ 已生成 WordPress 插件主文件" # ============ 5. 生成前端测试页面 ============ cat > "$FRONTEND_TEST" << EOF <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <title>WebSocket 测试</title> <style> body { font-family: Arial, sans-serif; padding: 20px; } #logs { list-style: none; padding: 0; max-height: 400px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; } li { margin: 5px 0; color: #333; } .sent { color: #0073aa; } .received { color: #51a351; } </style> </head> <body> <h1>WebSocket IM 测试</h1> <div id="status">状态:尝试连接...</div> <ul id="logs"></ul> <div style="margin-top: 20px;"> <input type="text" id="msgInput" placeholder="输入消息" style="width: 300px; padding: 5px;" /> <button onclick="sendMsg()">发送</button> </div> <script> const WS_URL = "wss://$DOMAIN/im-ws"; const ws = new WebSocket(WS_URL); let userId = "guest_" + Date.now(); let userName = "游客"; function log(msg, cls = "") { const li = document.createElement("li"); li.className = cls; li.textContent = new Date().toLocaleTimeString() + " - " + msg; document.getElementById("logs").appendChild(li); console.log(msg); } ws.onopen = () => { log("✅ 连接成功!"); document.getElementById("status").textContent = "✅ 已连接"; // 尝试从全局变量获取 WordPress 用户 if (typeof WP_IM_USER !== "undefined" && WP_IM_USER) { userId = WP_IM_USER.id; userName = WP_IM_USER.name; } else { userId = "test_user_" + Date.now(); userName = "测试用户"; } ws.send(JSON.stringify({ type: "register", userId: userId, userName: userName })); }; ws.onmessage = (e) => { const data = JSON.parse(e.data); if (data.type === 'user_online') { log("🟢 " + data.userName + " 上线了", "received"); } else if (data.type === 'user_offline') { log("🔴 " + data.userName + " 下线了", "received"); } else if (data.type === 'chat_message') { log("💬 [" + data.time + "] " + data.fromUserName + ": " + data.content, "received"); } else if (data.type === 'welcome') { log("👋 " + data.message, "received"); } }; ws.onerror = (e) => { log("❌ 错误: " + JSON.stringify(e)); document.getElementById("status").textContent = "❌ 连接失败"; }; ws.onclose = (e) => { log(\`⚠️ 连接关闭: \${e.code} \${e.reason}\`); document.getElementById("status").textContent = "⚠️ 已断开"; }; function sendMsg() { const input = document.getElementById("msgInput"); const val = input.value.trim(); if (val) { ws.send(JSON.stringify({ type: "chat", content: val })); log("你: " + val, "sent"); input.value = ""; } } // 回车发送 document.getElementById("msgInput").addEventListener("keypress", (e) => { if (e.key === "Enter") sendMsg(); }); </script> </body> </html> EOF echo "✅ 已生成前端测试页面: $FRONTEND_TEST" # ============ 6. 生成 Nginx 配置片段 ============ NGINX_SNIPPET=$(cat << 'EOF' location /im-ws { proxy_pass http://127.0.0.1:2121; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } EOF ) echo "📌 Nginx 配置建议(请复制到 $NGINX_CONF 的 server 块中):" echo echo "$NGINX_SNIPPET" echo echo "📌 保存后重启 Nginx: systemctl restart nginx" # ============ 7. 生成 systemd 服务 ============ cat > "$SYSTEMD_SERVICE" << EOF [Unit] Description=WordPress IM WebSocket Server After=network.target [Service] Type=simple User=$WORKER_USER WorkingDirectory=$PLUGIN_DIR ExecStart=/usr/bin/php im-server.php start ExecStop=/usr/bin/php im-server.php stop Restart=always StandardOutput=append:/var/log/wp-im-server.log StandardError=append:/var/log/wp-im-server.log [Install] WantedBy=multi-user.target EOF echo "✅ 已生成 systemd 服务: $SYSTEMD_SERVICE" echo "启用命令: sudo systemctl enable wp-im-server && sudo systemctl start wp-im-server" # ============ 8. 设置日志权限 ============ touch /var/log/wp-im-server.log chown $WORKER_USER:$WORKER_USER /var/log/wp-im-server.log chmod 644 /var/log/wp-im-server.log # ============ 9. 提示完成 ============ echo echo "🎉 部署完成!下一步操作:" echo echo "1. 🔧 编辑 Nginx 配置:" echo " nano $NGINX_CONF" echo " 将上面的 location /im-ws {...} 块粘贴进去" echo echo "2. 🔄 重启 Nginx:" echo " systemctl restart nginx" echo echo "3. ▶️ 启动 WebSocket 服务:" echo " sudo systemctl start wp-im-server" echo echo "4. 🌐 访问测试页:" echo " https://$DOMAIN/websocket-test.html" echo echo "5. 📂 查看日志:" echo " tail -f /tmp/workerman_stdout.log" echo " tail -f /var/log/wp-im-server.log" echo echo "💡 提示:确保宝塔防火墙或云服务器安全组放行 443 端口。" # ============ 3. 使用 Composer 安装 Workerman ============ echo "📦 初始化 Composer 并安装 Workerman..." cd "$PLUGIN_DIR" # 创建 composer.json(如果不存在) if [ ! -f "composer.json" ]; then cat > composer.json << 'EOF' { "name": "your-company/wp-im-plugin", "description": "WebSocket IM plugin for WordPress", "type": "project", "require": { "workerman/workerman": "^4.1" }, "autoload": { "psr-4": {} }, "config": { "allow-plugins": { "composer/installers": true } } } EOF fi # 安装依赖(仅生产环境需要 autoload) if [ ! -d "vendor" ] || [ ! -f "vendor/autoload.php" ]; then if ! command -v composer &> /dev/null; then echo "⚠️ Composer 未安装,尝试全局安装..." curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer fi # 执行安装(不带 dev 依赖) COMPOSER_PROCESS_TIMEOUT=200 composer install --no-dev --optimize-autoloader else echo "✅ vendor 已存在,跳过 Composer 安装" fi echo "✅ Workerman 已通过 Composer 安装" 请生成完整版源文件
11-14
#!/bin/bash ======================================================== WordPress + Workerman WebSocket IM 一键部署脚本(Composer 版) 功能:自动创建插件目录、生成服务文件、前端测试页、Nginx 配置、systemd 服务 支持自动安装 Composer 和 workerman/workerman 使用:chmod +x install-wp-im.sh && ./install-wp-im.sh --domain yfw.szrengjing.com --site-root /www/wwwroot/yfw_szrengjing_com ======================================================== set -e # 出错即停止 ============ 参数解析 ============ DOMAIN=“” SITE_ROOT=“” HELP=false while [[ “$#” -gt 0 ]]; do case $1 in –domain) DOMAIN=“$2”; shift ;; –site-root) SITE_ROOT=“$2”; shift ;; -h|–help) HELP=true; break ;; *) echo “未知参数: $1” >&2; exit 1 ;; esac shift done if [ “$HELP” = true ]; then cat << EOF 用法: $0 --domain <域名> --site-root <网站根目录> 示例: $0 --domain yfw.szrengjing.com --site-root /www/wwwroot/yfw_szrengjing_com 功能: 创建 WordPress 插件目录 自动生成 im-server.php (Workerman) 使用 Composer 安装 workerman/workerman 生成前端测试页面 websocket-test.html 生成 systemd 开机自启服务 提供 Nginx 反向代理配置片段 EOF exit 0 fi if [ -z “$DOMAIN” ] || [ -z “$SITE_ROOT” ]; then echo “❌ 错误: 必须指定 --domain 和 --site-root” echo “运行 $0 --help 查看帮助” exit 1 fi ============ 变量定义 ============ PLUGIN_NAME=“wp-im-plugin” PLUGIN_DIR=“$SITE_ROOT/wp-content/plugins/$PLUGIN_NAME” IM_SERVER=“$PLUGIN_DIR/im-server.php” WP_PLUGIN_MAIN=“$PLUGIN_DIR/$PLUGIN_NAME.php” FRONTEND_TEST=“ � � � � � � � � / � � � � � � � � � − � � � � . ℎ � � � " � � � � � � � � � = " / � � � / � � � � � � / � � � � � / � ℎ � � � / � � � � � / SITE R ​ OOT/websocket−test.html"NGINX C ​ ONF="/www/server/panel/vhost/nginx/{DOMAIN}.conf” SYSTEMD_SERVICE=“/etc/systemd/system/wp-im-server.service” LOG_FILE=“/var/log/wp-im-server.log” WORKER_USER=“www” # 宝塔默认 PHP 运行用户 echo “🚀 开始部署 WebSocket IM 系统” echo “🌐 域名: $DOMAIN” echo “📁 网站根目录: $SITE_ROOT” echo “🔌 插件路径: $PLUGIN_DIR” ============ 1. 创建插件目录 ============ echo “📁 创建插件目录…” mkdir -p “$PLUGIN_DIR” ============ 2. 生成 im-server.php (基于 Composer Autoload) ============ cat > “$IM_SERVER” << ‘EOF’ #!/usr/bin/env php <?php /** * Workerman WebSocket Server for WordPress IM * 使用 Composer 自动加载 */ use Workerman\Worker; use Workerman\Connection\TcpConnection; // 引入 Composer 自动加载器 require_once __DIR__ . '/vendor/autoload.php'; $worker = new Worker('websocket://0.0.0.0:2121'); $worker->name = 'WP_IM_Server'; $worker->count = 1; $worker->user = 'www'; $worker->onWorkerStart = function () { file_put_contents('/tmp/workerman_stdout.log', "✅ IM Server started at " . date('Y-m-d H:i:s') . "\n", FILE_APPEND); }; $worker->onConnect = function (TcpConnection $conn) { $conn->userId = null; $conn->userName = null; file_put_contents('/tmp/workerman_stdout.log', "🔗 新连接来自 {$conn->getRemoteIp()}:{$conn->getRemotePort()}\n", FILE_APPEND); }; $worker->onMessage = function (TcpConnection $conn, $data) use ($worker) { try { $msg = json_decode($data, true, 512, JSON_THROW_ON_ERROR); if ($msg['type'] === 'register') { $userId = $msg['userId'] ?? ''; $userName = htmlspecialchars($msg['userName'] ?? ''); if (!is_numeric($userId) || intval($userId) <= 0) { $conn->send(json_encode(['type' => 'error', 'message' => '非法用户ID'])); $conn->close(); return; } $conn->userId = $userId; $conn->userName = $userName; // 广播上线消息(除自己外) $online_msg = json_encode([ 'type' => 'user_online', 'userId' => $userId, 'userName' => $userName, 'time' => date('H:i') ]); foreach ($worker->connections as $c) { if ($c !== $conn) { $c->send($online_msg); } } // 欢迎自己 $conn->send(json_encode([ 'type' => 'welcome', 'message' => "欢迎回来,{$userName}" ])); file_put_contents('/tmp/workerman_stdout.log', "👤 用户 {$userId}({$userName}) 上线\n", FILE_APPEND); } if ($msg['type'] === 'chat') { $content = htmlspecialchars($msg['content'] ?? ''); if (empty($content)) return; $fromName = $conn->userName ?: '匿名'; $fromId = $conn->userId ?: '0'; $chat_msg = json_encode([ 'type' => 'chat_message', 'fromUserId' => $fromId, 'fromUserName' => $fromName, 'content' => $content, 'time' => date('H:i') ]); foreach ($worker->connections as $c) { $c->send($chat_msg); } file_put_contents('/tmp/workerman_stdout.log', "💬 聊天: [{$fromName}] {$content}\n", FILE_APPEND); } } catch (Exception $e) { file_put_contents('/tmp/workerman_stdout.log', "⚠️ 消息解析失败: {$e->getMessage()}\n", FILE_APPEND); } }; $worker->onClose = function (TcpConnection $conn) use ($worker) { if ($conn->userId && $conn->userName) { $offline_msg = json_encode([ 'type' => 'user_offline', 'userId' => $conn->userId, 'userName' => $conn->userName, 'time' => date('H:i') ]); foreach ($worker->connections as $c) { if ($c !== $conn) { $c->send($offline_msg); } } file_put_contents('/tmp/workerman_stdout.log', "👋 用户 {$conn->userId}({$conn->userName}) 下线\n", FILE_APPEND); } }; // 启动服务 if (basename(__FILE__) == 'im-server.php') { Worker::runAll(); } EOF # 给 im-server.php 添加执行权限 chmod +x "$IM_SERVER" echo "✅ 已生成并授权 im-server.php" # ============ 3. 使用 Composer 安装 Workerman ============ echo "📦 初始化 Composer 并安装 workerman/workerman..." cd "$PLUGIN_DIR" # 如果没有 composer.json,则创建 if [ ! -f "composer.json" ]; then cat > composer.json << 'EOF' { "name": "your-company/wp-im-plugin", "description": "WebSocket IM plugin for WordPress", "type": "project", "require": { "workerman/workerman": "^4.1" }, "config": { "allow-plugins": true } } EOF echo "📄 已创建 composer.json" else echo "📄 已存在 composer.json,跳过创建" fi # 检查是否已安装 vendor if [ ! -d "vendor" ] || [ ! -f "vendor/autoload.php" ]; then # 检查 composer 是否存在 if ! command -v composer &> /dev/null; then echo "⬇️ Composer 未安装,正在全局安装..." curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer echo "✅ Composer 已安装到 /usr/local/bin/composer" fi echo "⬇️ 正在执行 composer install..." COMPOSER_PROCESS_TIMEOUT=300 composer install --no-dev --optimize-autoloader else echo "✅ vendor 目录已存在,跳过 Composer 安装" fi echo "✅ Workerman 依赖通过 Composer 成功安装" # ============ 4. 生成 WordPress 主插件文件 ============ cat > "$WP_PLUGIN_MAIN" << EOF <?php /** * Plugin Name: WP IM Plugin * Description: 实时聊天系统,集成 Workerman WebSocket * Version: 1.0 * Author: Admin */ // 阻止直接访问 if (!defined('ABSPATH')) exit; // 前端注入当前用户信息 function wp_im_get_current_user_json() { if (is_user_logged_in()) { \$user = wp_get_current_user(); echo '<script>window.WP_IM_USER = {id: "' . esc_js(\$user->ID) . '", name: "' . esc_js(\$user->display_name) . '"};</script>'; } else { echo '<script>window.WP_IM_USER = null;</script>'; } } add_action('wp_head', 'wp_im_get_current_user_json'); EOF echo "✅ 已生成 WordPress 插件主文件: $WP_PLUGIN_MAIN" # ============ 5. 生成前端测试页面 ============ cat > "$FRONTEND_TEST" << EOF <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <title>WebSocket IM 测试</title> <style> body { font-family: Arial, sans-serif; padding: 20px; } #logs { list-style: none; padding: 0; max-height: 400px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; } li { margin: 5px 0; color: #333; } .sent { color: #0073aa; } .received { color: #51a351; } </style> </head> <body> <h1>WebSocket IM 测试</h1> <div id="status">状态:尝试连接...</div> <ul id="logs"></ul> <div style="margin-top: 20px;"> <input type="text" id="msgInput" placeholder="输入消息" style="width: 300px; padding: 5px;" /> <button onclick="sendMsg()">发送</button> </div> <script> const WS_URL = "wss://$DOMAIN/im-ws"; const ws = new WebSocket(WS_URL); let userId = "guest_" + Date.now(); let userName = "游客"; function log(msg, cls = "") { const li = document.createElement("li"); li.className = cls; li.textContent = new Date().toLocaleTimeString() + " - " + msg; document.getElementById("logs").appendChild(li); console.log(msg); } ws.onopen = () => { log("✅ 连接成功!"); document.getElementById("status").textContent = "✅ 已连接"; if (typeof WP_IM_USER !== "undefined" && WP_IM_USER) { userId = WP_IM_USER.id; userName = WP_IM_USER.name; } else { userId = "test_user_" + Date.now(); userName = "测试用户"; } ws.send(JSON.stringify({ type: "register", userId: userId, userName: userName })); }; ws.onmessage = (e) => { const data = JSON.parse(e.data); if (data.type === 'user_online') { log("🟢 " + data.userName + " 上线了", "received"); } else if (data.type === 'user_offline') { log("🔴 " + data.userName + " 下线了", "received"); } else if (data.type === 'chat_message') { log("💬 [" + data.time + "] " + data.fromUserName + ": " + data.content, "received"); } else if (data.type === 'welcome') { log("👋 " + data.message, "received"); } }; ws.onerror = (e) => { log("❌ 错误: " + JSON.stringify(e)); document.getElementById("status").textContent = "❌ 连接失败"; }; ws.onclose = (e) => { log(\`⚠️ 连接关闭: \${e.code} \${e.reason}\`); document.getElementById("status").textContent = "⚠️ 已断开"; }; function sendMsg() { const input = document.getElementById("msgInput"); const val = input.value.trim(); if (val) { ws.send(JSON.stringify({ type: "chat", content: val })); log("你: " + val, "sent"); input.value = ""; } } document.getElementById("msgInput").addEventListener("keypress", (e) => { if (e.key === "Enter") sendMsg(); }); </script> </body> </html> EOF echo "✅ 已生成前端测试页面: $FRONTEND_TEST" # ============ 6. 生成 Nginx 配置建议 ============ cat << 'EOF' 📌【重要】请将以下 Nginx 配置添加到你的站点配置中: server { # ... 其他配置 ... location /im-ws { proxy_pass http://127.0.0.1:2121; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } # ... 其他配置 ... } 📌 保存后重启 Nginx: systemctl restart nginx EOF # ============ 7. 生成 systemd 服务 ============ cat > "$SYSTEMD_SERVICE" << EOF [Unit] Description=WordPress IM WebSocket Server After=network.target [Service] Type=simple User=$WORKER_USER Group=$WORKER_USER WorkingDirectory=$PLUGIN_DIR ExecStart=/usr/bin/php im-server.php start ExecStop=/usr/bin/php im-server.php stop Restart=always StandardOutput=append:$LOG_FILE StandardError=append:$LOG_FILE [Install] WantedBy=multi-user.target EOF echo "✅ 已生成 systemd 服务: $SYSTEMD_SERVICE" echo "🔧 启用命令:" echo " sudo systemctl daemon-reexec" echo " sudo systemctl enable wp-im-server" echo " sudo systemctl start wp-im-server" # ============ 8. 创建日志文件并设置权限 ============ touch "$LOG_FILE" chown "$WORKER_USER:$WORKER_USER" "$LOG_FILE" chmod 644 "$LOG_FILE" echo "✅ 日志文件已创建: $LOG_FILE" # ============ 9. 设置插件目录权限 ============ chown -R "$WORKER_USER:$WORKER_USER" "$PLUGIN_DIR" echo "✅ 插件目录权限已设置为 $WORKER_USER" # ============ 10. 完成提示 ============ cat << EOF 🎉 ========================================= WebSocket IM 系统部署完成! 你可以进行下一步操作: ========================================== 1️⃣ 🔧 编辑 Nginx 配置: nano $NGINX_CONF 将上面的 location /im-ws {...} 块粘贴进 server {} 中 2️⃣ 🔄 重启 Nginx: systemctl restart nginx 3️⃣ ▶️ 启动 WebSocket 服务: sudo systemctl start wp-im-server 4️⃣ 🔍 查看服务状态: sudo systemctl status wp-im-server 5️⃣ 📂 查看运行日志: tail -f /tmp/workerman_stdout.log tail -f $LOG_FILE 6️⃣ 🌐 访问测试页面: https://$DOMAIN/websocket-test.html 💡 注意事项: - 确保服务器防火墙/安全组开放 443 和 2121 端口(2121 可不对外暴露) - 若修改了 im-server.php,需重启服务生效 - 生产环境建议增加 JWT 或 Cookie 校验身份 💪 你现在可以实现:用户登录 → 自动注册 WebSocket → 实时群聊! EOF 根据历史会话 脚本sh 全面升级im全部完整版功能源码配 套文件 前端后端一次性自动化部署配置
最新发布
11-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值