文章目录

目的方案说说明实现过程与代码演示前端页面(Xterm.js)后端服务(Golang)

编译与测试总结

目的

WebTerminal是一个比较有意思的功能,让我们可以脱离专门的软件,在浏览器中就可以与Linux设备进行交互。这篇文章将对这个功能做个简单的说明与演示。

例程地址如下: https://github.com/NaisuXu/web-terminal-demo-with-golang-and-xterm

方案说说明

WebTerminal这个市面上叫法还是挺混乱的,大多数情况下还和WebSSH混在一起,两者本质上是有一些区别的。这里也把这两者混在一起列举下常见的几个方案:

上面这个情况常见都是用在运维管理等使用,可以在浏览器中管理多台设备或服务器。

上面这个情况也常用在运维管理等使用。

上面这个情况主要用于设备本身通过Web UI进行操作,想要更加高级的操作时可以直接通过终端进行。

这篇文章实现的是最后一种方式。另外因为我主要用在嵌入式Linux设备中,Web Server评估下来使用Golang是适应性和开发效率综合来说最好的。

实现过程与代码演示

前端页面(Xterm.js)

前端实现Terminal功能主要使用 Xterm.js 这个库,官方页面如下: https://xtermjs.org/

VS Code中的中终端窗口就是使用这个库的,其中后端使用 node-pty 。

安装了Node.js的情况下新建项目目录并进入,然后初始化项目并下载xterm库:

npm init -y

npm install xterm

新建 index.html 文件,文件内容如下:

这时候就可以测试 Xterm.js 的功能了,可以使用Terminal对象的 write 方法向终端窗口中输出内容,使用 onData 方法可以接收终端窗口中的键盘操作:

上面就是前端页面最核心的东西了,接下来只要处理与后端服务的数据交互即可。这里使用WebSocket方式,完成后的代码如下:

WebTerminal

后端服务(Golang)

安装了Go的环境下,在刚才同目录中,使用下面命令初始化项目:

go mod init webterminal

新建 main.go 文件,文件内容如下:

package main

import (

"embed"

"net/http"

"os/exec"

"github.com/creack/pty"

"github.com/olahol/melody"

)

//go:embed index.html node_modules/xterm/css/xterm.css node_modules/xterm/lib/xterm.js

var content embed.FS

func main() {

c := exec.Command("sh") // 系统默认shell交互程序

f, err := pty.Start(c) // pty用于调用系统自带的虚拟终端

if err != nil {

panic(err)

}

m := melody.New() // melody用于实现WebSocket功能

go func() { // 处理来自虚拟终端的消息

for {

buf := make([]byte, 1024)

read, err := f.Read(buf)

if err != nil {

return

}

// fmt.Println("f.Read: ", string(buf[:read]))

m.Broadcast(buf[:read]) // 将数据发送给网页

}

}()

m.HandleMessage(func(s *melody.Session, msg []byte) { // 处理来自WebSocket的消息

// fmt.Println("m.HandleMessage: ", string(msg))

f.Write(msg) // 将消息写到虚拟终端

})

http.HandleFunc("/webterminal", func(w http.ResponseWriter, r *http.Request) {

m.HandleRequest(w, r) // 访问 /webterminal 时将转交给melody处理

})

fs := http.FileServer(http.FS(content))

http.Handle("/", http.StripPrefix("/", fs)) // 设置静态文件服务

http.ListenAndServe("0.0.0.0:22333", nil) // 启动服务器,访问 http://本机(服务器)IP地址:22333/ 进行测试

}

代码比较简单,核心功能就是调用系统中的虚拟终端,然后通过WebSocket和网页进行双向通讯。

上面代码只是用于功能测试使用的,这个代码有个问题是并没有对每个客户端进行单独处理,所以打开多个网页时操作都会同步响应。

使用下面命令安装相关依赖:

go mod tidy

编译与测试

在项目目录下创建 build.sh 文件,文件内容如下:

#!/bin/sh

GOOS=linux GOARCH=amd64 go build -o webterminal_linux_x86-64

GOOS=linux GOARCH=arm GOARM=7 go build -o webterminal_linux_armv7

GOOS=linux GOARCH=arm GOARM=5 go build -o webterminal_linux_armv5

后面三行命令分别用于编译生成三个平台的程序,你也可以根据需要来编写。

使用下面命令进行编译(注意window中需要使用 git-bash 等操作):

# chmod +x ./build.sh

./build.sh

将编译生成的程序拷贝到对应的平台中就可以进行测试了。

linux_x86-64 (Ununtu 22.04 AMD Ryzen 5 PRO 4650U):

linux_armv5 (NUC980 Linux buildroot 5.10.103+ armv5tejl GNU/Linux):

这里没有测试 linux_armv7 平台,有条件的话可以找一个树莓派(4B)进行测试。

总结

基于Golang和Xterm.js实现WebTerminal功能原理上比较简单,实际应用时更多的是需要根据需求进行功能和使用上的优化。

原文链接:

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。