新年あけましておめでとうございます。本年もどうぞよろしくお願いいたします。
というわけで、Webブラウザで動くターミナルを実装してみたんです。NodeJSで。そしたらすごく簡単だった。って話です。
使うもの
- express
- pty.js
- socket.io
- xterm.js
- pug-static
インストール
npmでてきとうにインストールします。
npm init
npm install --save express pty.js pug-static socket.io xterm
サーバ実装
適当にかきます。xterm.jsの中身をexpress.staticで公開しつつ、viewはpugで書きます。
ブラウザとの通信はSocket.IOを使って、ブラウザとターミナルの間をそれぞれ中継してあげます。
'use strict'; const express = require('express') , app = express() , server = require('http').createServer(app) , pugStatic = require('pug-static') , Io = require('socket.io') , pty = require('pty.js') app.use('/xterm.js', express.static('node_modules/xterm')) app.use('/', pugStatic('views')) let io = new Io(server); io.on('connect', socket => { let term = pty.spawn('bash', [], { name: 'xterm-256color', cols: 80, rows: 24 }); term.on('data', d => socket.emit('data', d)); socket.on('data', d => term.write(d)); socket.on('disconnect', () => term.destroy()); }); server.listen(3000);
クライアント実装
こっちもてきとうに。これは、index.pugという名前でviewsディレクトリの中に保存して使います。
サーバ実装と同様に、Socket.IOでブラウザへの入出力を中継してあげます。
doctype html html head link(rel='stylesheet', href='/xterm.js/dist/xterm.css') body #terminal script(src='/xterm.js/dist/xterm.js') script(src='/socket.io/socket.io.js') script. var term = new Terminal(); var socket = io(); term.open(document.getElementById('terminal')); term.on('data', d => socket.emit('data', d)); socket.on('data', d => term.write(d));
おわり
あとはアクセスすると、bashが見れて、そのまま使えます。xterm.jsすごくって、vimとかtmuxとかちゃんと使えます。
ただ、この実装にユーザ認証が含まれていないので必ずユーザ認証して使ってください。