如何在浏览器上实现一个terminal

/ javascript / 没有评论 / 1635浏览

如何在浏览器上实现一个terminal

第一次使用 Jupyter 的 terminal 之时,我就觉得这个功能非常神奇,且大有用武之地。这不,现在都流行云服务器了,在浏览器上运行个 terminal 简直成了程序员的日常。无论走到哪,打开浏览器上的 terminal,中断的现场立刻复现,你可以快速进入编码状态。这就是 web terminal 的最大的好处,让我们和实际的机器通过网络联通了。可以想象,浏览器上运行的东西只会越来越多,云文档,云端 IDE 正在流行起来。

Jupyter 的 terminal 我研究了下,实现原理就是 websocket,xterm.js,如果需要将这个 terminal 嵌入到自己的网站项目中,还是要深入研究下,最好自己动手实现一个,使用 websocket 可以很容易实现一个最小的 demo,效果如下:

1

虽然实现了将服务器执行长命令的输出结果持续推送至浏览器,但没有实现terminal 的窗口特效,要实现这个,需要使用 xterm.js (https://github.com/xtermjs/xterm.js/), 于是我搜了下 xterm.js 的使用方法,我找到了 webssh,这是别人早已经写好的东西,正好符合我的需求,果断放弃自己实现,直接拿来使用并学习,这种感觉真好。先看两张图,可以大概看出功能点:

2

3

这个 webssh 的特点如下:支持 ssh 用户名密码登录,空密码也可以,支持公钥认证,terminal 可以全屏,调整窗口大小,自动检查服务器的默认编码并适配,这在 Jupyter 的 terminal 中是不可以的,所以对我来说是非常实用的 web 终端了。它的工作原理也非常清晰,如下:

+---------+     http     +--------+    ssh    +-----------+
| browser | <==========> | webssh | <=======> | ssh server|
+---------+   websocket  +--------+    ssh    +-----------+

安装和使用方法也简单,先通过 pip install webssh 进行安装,在命令行执行 wssh 即可在默认的 8888 端口启动 web terminal,也可以给定服务端的参数配置:

# start a http server with specified listen address and listen port
wssh --address='2.2.2.2' --port=8000

# start a https server, certfile and keyfile must be passed
wssh --certfile='/path/to/cert.crt' --keyfile='/path/to/cert.key'

# missing host key policy
wssh --policy=reject

# logging level
wssh --logging=debug

# log to file
wssh --log-file-prefix=main.log

# more options
wssh --help

还可以通过 url 参数来使用前端:

#Passing form data (password must be encoded in base64, privatekey not supported)
http://localhost:8888/?hostname=xx&username=yy&password=str_base64_encoded

#Passing a terminal background color
http://localhost:8888/#bgcolor=green

#Passing a user defined title
http://localhost:8888/?title=my-ssh-server

#Passing an encoding
http://localhost:8888/#encoding=gbk

#Passing a command executed right after login
http://localhost:8888/?command=pwd

#Passing a terminal type
http://localhost:8888/?term=xterm-256color

作者还提供来 docker,可以说非常方便了,源码也是开源的,见:https://github.com/huashengdun/webssh ,github star 1.5K,也是个优秀的个人项目。如果你也想把 terminal 搬到浏览器上,学习这个项目就足够了。

首发于公众号「Python七号」