You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过脚本调用wscat向WebSocket传递命令并保存输入输出?

解决WebSocket脚本发送命令时提前断开的问题

我明白你遇到的困扰了——手动用wscat能正常连接发命令,但写脚本时总是还没完成命令发送,连接就提前关闭了。这主要是因为WebSocket的异步特性,脚本没等异步操作完成就直接退出了。下面给你一个完整的Node.js实现方案,完全满足你的三个需求:

第一步:准备依赖

首先安装Node.js的WebSocket客户端包ws

npm install ws

第二步:完整脚本实现

创建一个ws-commands.js文件,内容如下:

const WebSocket = require('ws');
const fs = require('fs');
const path = require('path');

// 配置参数
const WS_URL = 'ws://your-websocket-server-url'; // 替换成你的WS地址
const COMMANDS = [
  'command1',
  'command2',
  'command3' // 你的命令列表
];
const LOG_FILE = path.join(__dirname, 'ws-interaction.log'); // 日志保存路径

// 写入日志的工具函数
function writeLog(message) {
  const timestamp = new Date().toISOString();
  const logLine = `[${timestamp}] ${message}\n`;
  fs.appendFileSync(LOG_FILE, logLine);
  console.log(logLine.trim()); // 同时打印到控制台
}

// 发送单条命令并等待响应的函数
async function sendCommand(ws, command) {
  return new Promise((resolve, reject) => {
    // 设置超时,防止一直等不到响应
    const timeout = setTimeout(() => {
      reject(new Error(`Command "${command}" timed out`));
    }, 5000);

    // 监听响应
    const onMessage = (data) => {
      clearTimeout(timeout);
      ws.removeListener('message', onMessage); // 移除监听避免干扰下一条命令
      const response = data.toString();
      writeLog(`> 发送命令: ${command}`);
      writeLog(`< 收到响应: ${response}`);
      resolve(response);
    };

    ws.on('message', onMessage);
    ws.send(command);
  });
}

// 主流程
async function run() {
  writeLog('开始连接WebSocket服务器...');
  const ws = new WebSocket(WS_URL);

  await new Promise((resolve, reject) => {
    // 连接成功
    ws.on('open', () => {
      writeLog('WebSocket连接成功');
      resolve();
    });

    // 连接失败
    ws.on('error', (error) => {
      writeLog(`连接失败: ${error.message}`);
      reject(error);
    });

    // 意外关闭
    ws.on('close', (code, reason) => {
      writeLog(`连接意外关闭,代码: ${code}, 原因: ${reason}`);
      reject(new Error('Connection closed unexpectedly'));
    });
  });

  try {
    // 逐条发送命令
    for (const cmd of COMMANDS) {
      await sendCommand(ws, cmd);
      // 可选:如果需要在命令之间加延迟,取消下面这行注释
      // await new Promise(resolve => setTimeout(resolve, 1000));
    }

    writeLog('所有命令执行完成,关闭连接');
    ws.close();
  } catch (error) {
    writeLog(`执行出错: ${error.message}`);
    ws.close();
    process.exit(1);
  }
}

run();

关键细节解释

  • 异步顺序处理:用async/await和Promise确保每条命令发送后,等待响应返回再处理下一条,彻底避免脚本提前退出的问题。
  • 日志记录:通过writeLog函数同时把交互内容写入文件和打印到控制台,方便后续回溯所有操作。
  • 超时处理:每条命令设置5秒超时,防止因为服务器无响应导致脚本一直卡住。
  • 连接状态监听:全面处理连接成功、失败、意外关闭的情况,让脚本更健壮。

使用方法

  1. 替换脚本中的WS_URL为你的WebSocket服务器地址,COMMANDS为你的实际命令列表。
  2. 运行脚本:
node ws-commands.js
  1. 查看生成的ws-interaction.log文件,里面完整保存了所有的输入命令和输出响应。

内容的提问来源于stack exchange,提问作者Krzysztof

火山引擎 最新活动