基于 net.Server 和 net.Socket 的全功能 "terminal" REPL


¥Full-featured "terminal" REPL over net.Server and net.Socket

这是一个关于如何使用 net.Servernet.Socket 运行 "full-featured"(终端)REPL 的示例。

¥This is an example on how to run a "full-featured" (terminal) REPL using net.Server and net.Socket

以下脚本在端口 1337 上启动一个 HTTP 服务器,允许客户端与其 REPL 实例建立套接字连接。

¥The following script starts an HTTP server on port 1337 that allows clients to establish socket connections to its REPL instance.

// repl-server.js
import repl from 'node:repl';
import net from 'node:net';

net
  .createServer((socket) => {
    const r = repl.start({
      prompt: `socket ${socket.remoteAddress}:${socket.remotePort}> `,
      input: socket,
      output: socket,
      terminal: true,
      useGlobal: false,
    });
    r.on('exit', () => {
      socket.end();
    });
    r.context.socket = socket;
  })
  .listen(1337);// repl-server.js
const repl = require('node:repl');
const net = require('node:net');

net
  .createServer((socket) => {
    const r = repl.start({
      prompt: `socket ${socket.remoteAddress}:${socket.remotePort}> `,
      input: socket,
      output: socket,
      terminal: true,
      useGlobal: false,
    });
    r.on('exit', () => {
      socket.end();
    });
    r.context.socket = socket;
  })
  .listen(1337);

以下代码实现了一个客户端,它可以通过端口 1337 与上述定义的服务器建立套接字连接。

¥While the following implements a client that can create a socket connection with the above defined server over port 1337.

// repl-client.js
import net from 'node:net';
import process from 'node:process';

const sock = net.connect(1337);

process.stdin.pipe(sock);
sock.pipe(process.stdout);

sock.on('connect', () => {
  process.stdin.resume();
  process.stdin.setRawMode(true);
});

sock.on('close', () => {
  process.stdin.setRawMode(false);
  process.stdin.pause();
  sock.removeListener('close', done);
});

process.stdin.on('end', () => {
  sock.destroy();
  console.log();
});

process.stdin.on('data', (b) => {
  if (b.length === 1 && b[0] === 4) {
    process.stdin.emit('end');
  }
});// repl-client.js
const net = require('node:net');

const sock = net.connect(1337);

process.stdin.pipe(sock);
sock.pipe(process.stdout);

sock.on('connect', () => {
  process.stdin.resume();
  process.stdin.setRawMode(true);
});

sock.on('close', () => {
  process.stdin.setRawMode(false);
  process.stdin.pause();
  sock.removeListener('close', done);
});

process.stdin.on('end', () => {
  sock.destroy();
  console.log();
});

process.stdin.on('data', (b) => {
  if (b.length === 1 && b[0] === 4) {
    process.stdin.emit('end');
  }
});

要运行此示例,请在你的计算机上打开两个不同的终端,在一个终端中使用 node repl-server.js 启动服务器,在另一个终端中使用 node repl-client.js 启动服务器。

¥To run the example open two different terminals on your machine, start the server with node repl-server.js in one terminal and node repl-client.js on the other.

来自 https://gist.github.com/TooTallNate/2209310 的原始代码。

¥Original code from https://gist.github.com/TooTallNate/2209310.