React函数组件使用X-term结合webscoket实现前端页面shell登陆

897 阅读3分钟

使用Xterm结合webscoket实现了前端输入shell命令到K8s流式处理,这期间遇到了很多问题和特殊情况网上都没有可以搜寻借鉴的,我们一点点定位然后进行解决,所以在这里做一个总结。因为我们从完全没有接触过XTerm到完整做出来产品,也是借鉴了一些他人的经验分享的,所以如今也分享出来希望可以帮助到同样遇到坑的同学,但是原创不易,请不要进行搬运,尊重他人劳动成果。

  1. 最开始借鉴网上别人代码去初始化Xterm时,出现有个中文框,至今不知道因为什么(在后面整理代码重写一遍之后这个情况没有了),但是在最开始出现的时候,就是输入一切正常但是中文白框一直在,可能是下的依赖有问题,选择解决方式是更改这块的div块为``` { opacity:0; }

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/392ef7e736c0407bab4b9cea55621b3f~tplv-k3u1fbpfcp-watermark.image?)

  1. 然后遇到了渲染类型为canvas时丢失光标,为dom时才有光标的现象,和官方文档写的定义是相反的,这个后面也是重新写了就好了 不太知道为啥。换成dom渲染类型之后,背景会是自动白色。

image.png 效果图如下

image.png

那个多余的W也是通过透明度为0 解决掉了。**不过最后一次整理代码用了官方的css文件,就没有上述两个问题了 **,可能有做处理。

  1. 在采用了流式处理后,前端不需要对输入的数据进行任何处理,不需要去判断鼠标和按键,k8S下的terminal会对输入的数据直接处理,包括复制、Tab补全,换行等等,也不需要前端启用websocket后去用onmessgae监听,也不需要将监听到的信息去term.write。 只需要 disableStdin: false, //是否应禁用输入。将此设为false,就可以去走Linux的studin。xterm初始化如下:

image.png

4.但是这个时候使用流式会发现xterm输入到一半就会强制换行的问题,没办法输入到头,就是前端看似xterm黑色屏幕放大了,但是并没有传给后台真正的terminal接收,输入还是只能那样的大小,而且因为使用了Stdin,此时再使用xterm的onResize并不生效。为了解决这个问题我的师兄木南花了好长时间来定位去解决。还是用流,但是支持resize,木南师兄在后端做了了unmarshal,就是前端的JSON.parse的异常容错。 监听window大小,并将size传给后台,使用term.cols和rows来匹配。

image.png

  1. 就当前业务场景,我需要一进页面在useEffect里去建立webscoket通道,但是我的页面还有一个按钮需要来主动关闭websocket,我按钮里的onClcik事件如论怎样都访问不到页面初始进来开启的那个websocket,最后解决办法为,定义websocket为useRef,这个好用的全局变量,不会在state改变时被重复渲染。

image.png