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

    技术2024-11-23  17

    阅读本文大概需要 5 分钟。

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

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

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

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

    安装和使用方法也简单,先通过 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 搬到浏览器上,学习这个项目就足够了。

    相关阅读:

    既生 HTTP 何生 WebSocket ?

    Processed: 0.087, SQL: 9