Xterm.js: ZModem ์ง€์›?

์— ๋งŒ๋“  2016๋…„ 09์›” 19์ผ  ยท  41์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: xtermjs/xterm.js

lrzsz๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์„ ์ˆ˜์‹ /์ „์†กํ•  ์ˆ˜ ์žˆ๋„๋ก ZModem์„ ์ง€์›ํ•ฉ๋‹ˆ๊นŒ? ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๊นŒ?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

xterm ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ด๊ฒƒ์˜ ๋ชจ์–‘์— ๋Œ€ํ•ด 2์„ผํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด: 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 ๊ตฌํ˜„์ด ์žˆ์Œ) ๋ธŒ๋ผ์šฐ์ €์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ ์•ก์„ธ์Šค๊ฐ€ ๋งค์šฐ ์ œํ•œ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์šฉ์„ฑ์— ์˜๋ฌธ์„ ์ œ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ์–ด๋ ค์šด ๋ถ€๋ถ„์€ ํฐ ํŒŒ์ผ์— ๋Œ€ํ•ด ๋ธŒ๋ผ์šฐ์ €์™€ ๋‹ค์šด๋กœ๋“œ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋ฐ์ดํ„ฐ๊ฐ€ ์›น ์†Œ์ผ“์„ ํ†ตํ•ด ๋ธŒ๋ผ์šฐ์ €์— ์ง์ ‘ ๋„์ฐฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— 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 ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ์ชฝ์—์„œ ์ง์ ‘ ํŒŒ์ผ์„ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด ํ„ฐ๋ฏธ๋„ ์—ฐ๊ฒฐ์„ "๋‚จ์šฉ"ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ผ ํ„ฐ๋ฏธ๋„ ์„ธ์…˜์„ ํ†ตํ•ด์„œ๋งŒ ์„œ๋ฒ„๋ฅผ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. POSIX ์‹œ์Šคํ…œ์˜ ๊ฒฝ์šฐ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ rz / sz ๋„๊ตฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

xterm.js์˜ ๊ฒฝ์šฐ ์™„๋ฒฝํ•œ ์• ๋“œ์˜จ์ด๋ฉฐ ์ œํ•œ๋œ ํ™˜๊ฒฝ์˜ ์„œ๋ฒ„ ๊ด€๋ฆฌ์ž์—๊ฒŒ xterm.js์˜ ์œ ์šฉ์„ฑ์„ ๋†’์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. :+1:

์ฃผ์˜: XMODEM๊ณผ YMODEM์€ ๋ชจ๋‘ ์ƒ๋Œ€๋ฐฉ์—๊ฒŒ ํŒŒ์ผ ์ „์†ก ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” "ํ”„๋กฌํŠธ"๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. (ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ–‰ํ•ฉ๋‹ˆ๋‹ค!)

ZMODEM์€ ๋ณธ์งˆ์ ์œผ๋กœ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ๋Š” "๋งˆ๋ฒ•์˜ ๋ฌธ์ž์—ด"์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์‚ฌ์šฉ์ž์—๊ฒŒ "ZMODEM์ด ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ์ „์†ก์„ ๊ณ„์†ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?โ€ ์ด ์‹œ์ ์—์„œ ๊ตฌํ˜„์€ ์ „์†กํ•  ํŒŒ์ผ์„ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ๋ณด๋‚ธ ์‚ฌ๋žŒ์ด ์ œ๊ณตํ•˜๋Š” ํŒŒ์ผ์„ ์ˆ˜๋ฝ/๊ฑด๋„ˆ๋›ฐ๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

xterm.js์˜ ๊ฒฝ์šฐ ํŒŒ์ผ์„ ํ„ฐ๋ฏธ๋„์— ๋Œ์–ด๋‹ค ๋†“๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์ด ํ˜„์žฌ ํ„ฐ๋ฏธ๋„ ์…ธ ๊ฒฝ๋กœ์— ์ €์žฅ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ xterm.js๊ฐ€ ์›๊ฒฉ ์‰˜ ์ž์ฒด๋ฅผ ์ œ์–ดํ•˜๊ฑฐ๋‚˜ ์ ์–ด๋„ ํ˜„์žฌ ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์–ด๋Š ์‹œ์ ์—์„œ๋“  ์žก์„ ์ˆ˜ ์—†๋‹ค๋ฉด ๋‹ฌ์„ฑํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. ๊ฑฐ๊พธ๋กœ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ls ๋ชฉ๋ก์ด ์›๊ฒฉ ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ฐœ๊ฒฌ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ ๋Œ์–ด์„œ ๋†“๊ธฐ๊ฐ€ ๊น”๋”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธ€์Ž„ ๊ทธ๋ƒฅ ๊ฟˆ์„ ๊พธ๊ณ  ์žˆ๋‹ค :์œ™ํฌ:

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'

repo ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์•„๋‹Œ ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ npm install ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ž์—ด์ด ์•„๋‹Œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก node-pty๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ZMODEM์€ ๋ฐ”์ด๋„ˆ๋ฆฌ ํ”„๋กœํ† ์ฝœ์ด์ง€๋งŒ ๋ฐ๋ชจ์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด UTF-8์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ๋ญ”๊ฐ€ 0x8a๋ฅผ UTF-8๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค \ufffd

์ด๊ฒƒ์€ ์ข€ ๋” ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น ๋ฅธ ์ˆ˜์ •์„ ์œ„ํ•ด node-pty์˜ ์ธ์ฝ”๋”๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜ ๋ฌธ์ž์—ด ์œ ํ˜•์„ 'binary'๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ xterm.js๋กœ์˜ websocket ์ „์†ก์— ์›์น˜ ์•Š๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ์ „์ฒด ์ฒด์ธ node-pty <---> websocket <---> xterm.js ์€ ์ฆ‰์‹œ JS ๋ฌธ์ž์—ด๋กœ ๋””์ฝ”๋”ฉ๋˜๋Š” UTF-8 ๋ฐ”์ดํŠธ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์–ป์œผ๋ ค๋ฉด ๋” ํฐ ํŒจ์น˜๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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 ํ•„์š”ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.) ์—ฌ์ „ํžˆ ์‰˜ ์„ธ์…˜์˜ ์ฒซ ๋ฒˆ์งธ ๋ผ์ธ์„ ํ…์ŠคํŠธ๋กœ ๋ณด๋‚ด์ง€๋งŒ ๊ทธ ์ดํ›„์˜ ๋ชจ๋“  ๊ฒƒ์€ ๋ฐ”์ด๋„ˆ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ •๋ง ๋ฉ‹์ง‘๋‹ˆ๋‹ค.

์—ฌ์ „ํžˆ ์‰˜ ์„ธ์…˜์˜ ์ฒซ ๋ฒˆ์งธ ์ค„์„ ํ…์ŠคํŠธ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค...

{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 ๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. (ํฌ๋กฌ์€ ๋‚ด๊ฐ€ ํ…Œ์ŠคํŠธ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.)
6) lrzsz ์„ค์น˜๋œ ์ปดํ“จํ„ฐ์— ssh.
7) rz ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์›Œํฌ์Šคํ…Œ์ด์…˜์—์„œ ์›๊ฒฉ์œผ๋กœ ํ•˜๋‚˜ ์ด์ƒ์˜ ํŒŒ์ผ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
8) sz <filename1> <filename2> โ€ฆ ๋Š” ํŒŒ์ผ์„ ์ผ๊ด„์ ์œผ๋กœ ์›Œํฌ์Šคํ…Œ์ด์…˜์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

(UI๋Š” ์ตœ์†Œํ•œ์˜ ๋””์ž์ธ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ "์‹ค์ œ" ๋ฐฐํฌ๊ฐ€ ๋” ๋‹ค๋“ฌ์–ด์งˆ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.)

4๋‹จ๊ณ„์™€ ๊ด€๋ จํ•˜์—ฌ: ๋ฐฉ๊ธˆ ๋‚ด ์›Œํฌ์Šคํ…Œ์ด์…˜์—์„œ ํ…Œ์ŠคํŠธํ–ˆ์„ ๋•Œ node-gyp ํŒจํ‚ค์ง€์˜ ๊ถŒํ•œ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฉ‹์ง€๋‹ค. ๋งค๋ ฅ์ฒ˜๋Ÿผ ์ž‘๋™ํ•œ๋‹ค(Firefox์—์„œ ํ…์ŠคํŠธ ํŒŒ์ผ๋กœ ํ…Œ์ŠคํŠธ).

๋ช‡ ๊ฐ€์ง€ ์„ค๋ช…:

  • ์‹ค์ˆ˜๋กœ ์ดˆ๊ธฐํ™” ์‹œํ€€์Šค๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ(์˜ˆ: ์ž„์˜ ๋ฐ์ดํ„ฐ ์ถœ๋ ฅ)? ๊ทธ๋ ‡๋‹ค๋ฉด ํ„ฐ๋ฏธ๋„์€ ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด IMHO์— "ํŒŒ์ผ ์ „์†ก ์ž…๋ ฅ" ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • "ZMODEM ์„ธ์…˜ ์‹œ์ž‘"์€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ "์•„๋‹ˆ์˜ค"๋ฅผ ์„ ํƒํ•ด๋„ ๋‹ค๋ฅธ ์ชฝ atm์—์„œ rz ์ค‘๋‹จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ „์†ก์ด ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ ํ„ฐ๋ฏธ๋„ ์œ„์ ฏ์— ์ง„ํ–‰๋ฅ  ํ‘œ์‹œ์ค„/ํ‘œ์‹œ๊ธฐ๋ฅผ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜๋Š” ๋‹ค๋ฅธ ๋ฉ‹์ง„ ๊ฒƒ๋“ค, atm rz/sz ํ„ฐ๋ฏธ๋„์— ์ด์ƒํ•œ ์ƒํƒœ ๋ฒˆํ˜ธ๋ฅผ ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค.

@jerch

1) ์˜ˆ, ์‹ค์ˆ˜๋กœ ์ดˆ๊ธฐํ™” ์‹œํ€€์Šค๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด "ZMODEM ์„ธ์…˜ ์‹œ์ž‘" ํ”„๋กฌํ”„ํŠธ์˜ ๋ชฉ์ ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—ฌ์ „ํžˆ ๋’ค๋กœ ๋ฌผ๋Ÿฌ๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2) ์ง€๊ธˆ ๊ณ ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

3) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ธŒ๋ผ์šฐ์ €์˜ FileReader API์™€ ๋™๊ธฐํ™”ํ•˜์—ฌ progress ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค. Chrome์€ progress ์ฝ˜ํ…์ธ ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Firefox๋Š” ์‹ค์ œ๋กœ ํ•ด๋‹น ์ด๋ฒคํŠธ์—์„œ ํŒŒ์ผ ๋‚ด์šฉ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Chrome์—์„œ ์ ์ ˆํ•˜๊ฒŒ ํฐ ํŒŒ์ผ์„ ๋ณด๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
image

4) ์„ธ์…˜ ์‹œ์ž‘ ์‹œ ์ด์ƒํ•œ ๋ฌธ์ž๋Š” ZMODEM ์ˆ˜์‹  ์ดˆ๊ธฐํ™” ์‹œํ€€์Šค์˜ ์ธ์‡„ ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ** + ASCII CAN + B01 + 10์ง„์ˆ˜ ๋ฌธ์ž + CR + 0x8a + XON. ๋‚˜๋Š” ๊ทธ๋“ค์ด ํ™”๋ฉด์— ๊ฐ€๋Š” ๊ฒƒ์ด ์ถ”ํ•˜๋‹ค๋Š” ๊ฒƒ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ ZMODEM์— ์ •ํ†ตํ•œ ํ„ฐ๋ฏธ๋„์—์„œ ๊ฝค ํ‘œ์ค€์ ์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ฌธ์ž๋ฅผ ์‚ญ์ œํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•œ 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 ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ด๊ฒƒ์˜ ๋ชจ์–‘์— ๋Œ€ํ•ด 2์„ผํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด: 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๋ฅผ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ๋˜๋ฉด(https://github.com/tsl0922/ttyd/issues/37) ttyd์— ๋Œ€ํ•œ ZModem ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

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 ๋“ฑ๊ธ‰