Xterm.js: ZModem 支持吗?

创建于 2016-09-19  ·  41评论  ·  资料来源: xtermjs/xterm.js

支持 ZModem 以便我们可以使用 lrzsz 接收/发送文件? 这听起来有趣吗?

最有用的评论

如果我可以为它的形状添加两分钱以使其成为 xterm 插件:我建议根本不添加 UI,而是通过类似于节点流的事件调度事物。 就像是

term.on('transfer', (transfer) => {

  // accept or reject the transfer
  transfer.accept();

  // listen for progress
  transfer.on('progress', ...);

  // data chunks arrive
  transfer.on('data', ...);

  // transfer has finished
  transfer.once('end', ...);

  // cancel transfer
  transfer.abort();

});

通过这种方式,消费者可以在插件之上构建自己的 UI。

所有41条评论

您能否详细了解这将如何在 xterm.js 上工作?

我使用 xterm.js 连接到 bash(全功能 bash)并让用户与 bash 交互。 我希望支持用户使用 rz/sz 通过网络终端上传/下载文件。

如果我使用 SecureCRT/Xshell 连接到机器的外壳,我可以使用rz / sz命令上传/下载文件。 我想使用 zterm.js 连接到机器的外壳,并使用rz / sz命令上传/下载文件

Zmodem 是 PTY 系统底层串行线抽象的一个协议特性。 这已经可以用于 xterm.js 中的zssh工具。 xterm.js 本身只是将 PTY 的主 IO 转发到浏览器。 实际上,您正在托管 xterm.js 服务器部分的系统上运行。

这与像 SecureCRT 一样在同一台机器上运行的终端仿真器完全不同。

所以问题是 - 您想通过终端将文件从哪台机器移动到哪台机器? (请记住,您的本地机器没有到 xterm.js 服务器部分的终端通道)。

|       local machine               |
|   +----------------------------+  |
|   |       browser              |  |
|   |   +-------------------+    |  |               +---------------------------+          +------------------------+
|   |   |                   |    |  |               |   proxy                   |          |                        |
|   |   |   web terminal    >----------------------->   server part of xterm.js >----------| romote machine terminal|
|   |   |                   |    |  |               +---------------------------+          +------------------------+
|   |   |                   |    |  |
|   |   +-------------------+    |  |
|   +----------------------------+  |
+-----------------------------------+

我想将文件从本地机器移动到远程机器。 本地机器无法直接访问远程机器,因为它没有外部 ip。

请记住,您的本地机器没有到 xterm.js 服务器部分的终端通道

有什么解决方法吗?

好吧,您可以使用 zssh(支持 zmodem)、sftp 或来自代理的 scp。

除非有人实施它,否则无法直接从浏览器中的网络终端上传/下载文件到远程机器。 可以以这种方式使用其中一种调制解调器协议(有一个 XModem JS 实现),但由于浏览器的文件系统访问权限非常有限,我怀疑其实用性。 困难的部分是为大文件提供与浏览器的下载交互(由于数据通过 websocket 直接登陆浏览器,JS 必须保存所有数据,直到可以保存为止。)

另一种方法是使用 rz/sz 功能增强服务器部分,并将其透明地映射到浏览器。 这将绕过浏览器的 FS 限制,但需要将另一个解析器连接到终端流中以捕获调制解调器协议的“rz\r”初始化。

我一直在用 JavaScript 研究 ZMODEM 实现,并让它通过 xterm.js 双向传输文件。

浏览器确实必须在接收时缓冲整个文件。 :( 不过,这确实是唯一的缺点,除非您发送非常大的文件,否则这还不错。上传可以通过 FileReader 完成,下载可以通过<a>元素的“下载”属性进行。

我仍在测试和记录它,但是 ZMODEM 集成是 xterm.js 感兴趣的功能吗?

@FGasper Nice :) 听起来很有希望,如果您使用节点的流 API 实现它,它也可以用作服务器端扩展的大文件,通过下载链接将这些文件代理到浏览器端点。

该库本身与平台无关,因此它应该可以在任何地方使用。 (敲木头。)

@FGasper听起来不错😄!

我们绝对可以考虑使用 zmodem 插件,如果它在浏览器中工作的话。

使用 zmodem 通常有哪些用例?

我用它在终端会话中与我的工作站进行文件传输。 它使您不必使用 scp/sftp 或其他什么。

与 iTerm2 类似:
https://github.com/mmastrac/iterm2-zmodem

@parisk X/Y/Z-MODEM 协议允许“滥用”终端连接,以实现从另一rz / sz工具来完成此操作。

对于 xterm.js 来说,它是一个完美的插件,它将提高 xterm.js 在受限环境中的服务器管理员的实用性。 :+1:

注意:XMODEM 和 YMODEM 都有一个缺点,即不会“提示”对方准备好文件传输。 (很不幸,因为它们要简单得多!)

ZMODEM 发送本质上是一个可以被监视的“魔法字符串”; 然后你提示用户,“ZMODEM检测到; 继续文件传输?” 在这一点上,实现提供了提供文件传输或接受/跳过发送方提供的文件的方法。

对于 xterm.js,只需将文件拖放到终端中就可以了 - 假设文件保存在当前终端 shell 路径中。 但这很难完成,除非 xterm.js 可以控制远程 shell 本身或至少在任何时候获取当前工作目录。 倒退也是如此 - 如果ls列表可以被发现是指远程文件,那么拖出终端就可以了。 好吧只是在做梦:wink:

我不明白为什么在 Zmodem 会话启动后无法拖放rz 。 它可以通过多种方式实现,但也许:

1) 在控制台中输入rz
2)拖放文件。
3) 开始传输。

问题:xterm.js 如何设置仍然支持 IE?

由于https://github.com/sourcelair/xterm.js/pull/938在 v3 中不再支持 IE,无论如何开发人员都应该关闭它。

我想向大家展示一个演示。

我一直在测试我自己的终端服务器,但想使用你们默认的任何东西。

image
^^ 我在这里遗漏了什么吗? npm install错误给我...

felipe@Macintosh-4 18:00:56 ~/code/p5-Net-WebSocket/demo
> sudo npm install
npm ERR! install Couldn't read dependencies
npm ERR! Darwin 16.7.0
npm ERR! argv "/opt/local/bin/node" "/opt/local/bin/npm" "install"
npm ERR! node v8.3.0
npm ERR! npm  v2.15.12
npm ERR! path /Users/felipe/package.json
npm ERR! code ENOPACKAGEJSON
npm ERR! errno -2
npm ERR! syscall open

npm ERR! package.json ENOENT: no such file or directory, open '/Users/felipe/package.json'
npm ERR! package.json This is most likely not a problem with npm itself.
npm ERR! package.json npm can't find a package.json file in your current directory.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/felipe/code/p5-Net-WebSocket/demo/npm-debug.log

也许你忘记了git clone ... ? 为什么用sudo

@FGasper

npm ERR! package.json ENOENT: no such file or directory, open '/Users/felipe/package.json'

您正在主目录中运行npm install ,而不是 repo 目录。

有没有办法让 node-pty 输出二进制而不是字符串? ZMODEM 是一个二进制协议,但演示中似乎认为一切都是 UTF-8。 特别是,某些东西似乎正在将 0x8a 转换为 UTF-8 \ufffd

这可能涉及更多的问题 - 为了快速修复,您可以尝试禁用 node-pty 的编码器或将字符串类型设置为“二进制”,但这可能会对 websocket 传输到 xterm.js 产生不利影响。 据我所知,整个链node-pty <---> websocket <---> xterm.js依赖于 UTF-8 字节,这些字节被动态解码为 JS 字符串。 可能需要更大的补丁才能使二进制数据流动。

binary字符串类型设置在哪里? (我在 node-pty 中没有看到这样的?)

据我所知,数据在到达app.js时已经损坏,因此行为的变化必须在 node-pty 中。

ZMODEM 确实拼出了一种将所有高位字符转义为 7 位的编码,但它显然从未真正实现过...... Forsberg 可能认为它永远不会被需要,因为所有的行都变成了 8 位安全,呵呵。 :)

您可以尝试在 ctor 选项中使用{encoding: 'binary'}或动态使用.setEncoding('binary')

看起来最近的 node-pty 允许设置或不设置 UTF8 模式……

  if (info[8]->ToBoolean()->Value()) {
#if defined(IUTF8)
    term->c_iflag |= IUTF8;
#endif
}

https://github.com/Tyriar/node-pty/blob/master/src/unix/pty.cc

嗯……xterm.js 引入的 node-pty (0.4.1) 已经很老了……也许最新版本会包含那个标志。

调用.setEncoding('binary')不起作用……并且将encoding:"binary"传递给 pty.spawn() 也不起作用。

termios 的 IUTF8 做了不同的事情 - 它可以正确处理 pty 设备中的多字节 UTF8 字符(用于线宽和擦除)。
嗯也许很难 - 尝试移除编码器:

delete ptyObj._socket._readableState.decoder;
delete ptyObj._socket._readableState.encoding;

这应该给你缓冲对象而不是字符串(最有可能向上分解到 xterm.js)。

好的,我通过升级到 node-pty 0.6.4 并将编码设置为null 。 (不需要_readableState东西。)它仍然将 shell 会话的第一行作为文本发送,但之后的所有内容都是二进制的,太酷了。

它仍然将shell会话的第一行作为文本发送......

即使您将其作为{encoding: null}应用于构造函数?

是的,即使使用{encoding: null} ,第一行也是作为文本框架发送的。

我已经把它变成了我认为可以尝试的合理状态。

1) 将 https://github.com/FGasper/xterm.js.git 设置为远程。
2) 查看该 repo 的zmodem分支。
3) git submodule init; git submodule update
4) npm install (见下文)
5) npm start ,然后在浏览器中加载localhost:3000 。 (Chrome 是我测试过的。)
6) ssh 到安装了lrzsz机器。
7) 键入rz ,然后将一个或多个文件从您的工作站发送到远程。
8) sz <filename1> <filename2> …将批量发送文件到您的工作站。

(UI 的设计是最小的;假设“真正的”部署会更加完善它。)

关于第 4 步:当我刚刚在我的工作站上进行测试时,我不得不修复node-gyp包的权限问题。

很好,就像一个魅力(在 Firefox 中用文本文件测试)。

简单说几句:

  • 是否有可能意外触发 init 序列(例如随机数据输出)? 如果是这样,恕我直言,终端需要一个“输入文件传输”设置来明确这一点。
  • “启动 ZMODEM 会话”应该是可中断的,选择“否”不会中止另一端 atm 上的rz
  • 在传输过程中,是否可以在终端小部件中绘制一些进度条/指示器? 或者其他一些更花哨的东西,atm rz/sz在终端中打印一些奇怪的状态数字。

@jerch

1) 是的,可能会意外触发 init 序列。 这就是“启动 ZMODEM 会话”提示的用途:如果需要,用户仍然可以退出。

2)现在应该修复。

3) 应用程序接收与浏览器的 FileReader API 同步的progress事件。 Chrome 似乎提供了progress ; 但是,Firefox 实际上并未在这些事件中提供文件内容。 如果您在 Chrome 中向自己发送一个合适的大文件,您会看到如下内容:
image

4) 会话开始时的奇怪字符是 ZMODEM 接收初始化序列的可打印部分: ** + ASCII CAN + B01 + 10 个十六进制字符 + CR + 0x8a + XON。 我同意他们进入银幕是丑陋的; 然而,它在我使用过的 ZMODEM-savvy 终端中是非常标准的。 我想它可以向终端发送足够的 BS 字符来删除这些字符吗?

还需要添加一个控件来取消正在进行的传输。 我仍在寻找处理它的最佳方法。

还需要添加一个控件来取消正在进行的传输。 我仍在寻找处理它的最佳方法。

也许这从规格帮助?

A ZFIN, ZABORT, or TIMEOUT terminates the session; a ZSKIP terminates the processing of
this file.

潜在的。 规范并不总是最有用的东西; 例如,它提到在 ZSINIT 之后发送的 Attn 序列。 规范似乎表明这就是如何让发送者暂停数据发送,但显然没有实际使用 Attn。 与 ESC8 选项类似:它实际上并未在lrzsz ,而且由于这是事实上的参考实现,因此 ESC8 无法使用——这是一种耻辱,因为它可以很好地解决 termios IEXTEN 标志的问题。

我现在正忙于其他项目,但希望下周能回到这个项目。

如果我可以为它的形状添加两分钱以使其成为 xterm 插件:我建议根本不添加 UI,而是通过类似于节点流的事件调度事物。 就像是

term.on('transfer', (transfer) => {

  // accept or reject the transfer
  transfer.accept();

  // listen for progress
  transfer.on('progress', ...);

  // data chunks arrive
  transfer.on('data', ...);

  // transfer has finished
  transfer.once('end', ...);

  // cancel transfer
  transfer.abort();

});

通过这种方式,消费者可以在插件之上构建自己的 UI。

@mofux这就是我希望它也能正常工作的方式。 我放入演示中的 UI 组件仅用于演示控件。

@FGasper 干得好👍

当您的 api 准备好使用时,我将添加对 ttyd 的 ZModem 支持(https://github.com/tsl0922/ttyd/issues/37),感谢您的工作。

https://www.npmjs.com/package/zmodem.js

我已经发布了 zmodem.js 的 ALPHA 版本。 从这里我将查看 xterm.js 的插件界面,但是任何想要查看 zmodem.js 的人,请随时这样做,让我知道它是如何为您工作的。

ZMODEM 插件现已合并,仅供参考。

win7系统

$ npm run start-zmodem

> [email protected] start-zmodem E:\test\xterm\xterm.js
> node demo/zmodem/app

App listening to http://127.0.0.1:3100

为什么无法打开文件资源管理器?
default

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

albinekb picture albinekb  ·  4评论

circuitry2 picture circuitry2  ·  4评论

johnpoth picture johnpoth  ·  3评论

goxr3plus picture goxr3plus  ·  3评论

fabiospampinato picture fabiospampinato  ·  4评论