我希望展示在后端服务器上运行的长时间运行的 shell 命令的实时输出,包括 ANSI 转义代码渲染,就像 GitLab 显示 CI 管道输出的方式一样。例如:
是否有任何现有的库或框架可以提供此功能?我预计前端会通过在循环、websockets 或类似方法中使用 REST 调用从后端检索输出。看起来像 jQuery Terminal Emulator很近,但我不希望有一个交互式终端。该应用程序的堆栈目前在后端使用 Django Rest Framework,在前端使用 Vue.js。
最佳答案
这是一个相当宽泛的问题,但却是一个有趣的问题。我发现很难仅从代码的角度对此提供答案,但也许您会发现我的答案仍然有用。
有几种方法可以实现这一点:
- 将 ANSI 字符串转换为 HTML 并将其发送给客户
- 将ANSI字符串发送给客户端并要求他们转换
我选择了第二个,因为你似乎在后端使用 Python,而且我不太了解 Python 网络编程,无法为你提供完整的示例。在这种情况下,选项 2 限制了您必须在 Python 中复制的代码量才能获得如下所示的功能。
您可以找到包含前端和后端 (NodeJS) 代码的完整示例 here .后端只是一个 websocket 服务器,它将命令的输出通过管道传递给传入的连接。
对于输出,我尝试使用 apt update
和 top
,但是 apt update
在从 NodeJS 和 调用时不会渲染颜色输出code>top
会提示缺少 tty
。相反,我决定使用一个简单的 shell 脚本来生成具有随机 ANSI 颜色的字符串。大部分逻辑是从 this answer 借来的.
前端是一个非常简单的 Console
VueJS 组件,我在下面对其进行了描述。所有繁重的工作都由 ansi_up 完成库,我只是将它的输出直接用作组件的 HTML 内容。
<template>
<div class="console" v-html="html">
</div>
</template>
<script>
import AnsiUp from 'ansi_up'
export default {
name: 'shell',
props: ['socket'],
data () {
return {
ansi: undefined,
content: ''
}
},
computed: {
html () {
// Ensures we have some semblance of lines
return this.ansi.ansi_to_html(this.content).replace(/\n/gm, '<br>')
}
},
watch: {
socket () {
this.socket.on('data', data => {
this.content += data
})
this.socket.send('ready')
}
},
beforeMount () {
this.ansi = new AnsiUp()
},
updated () {
// auto-scroll to the bottom when the DOM is updated
this.$el.scrollTop = this.$el.scrollHeight
}
}
</script>
<style lang="scss" scoped>
.console {
font-family: monospace;
text-align: left;
background-color: black;
color: #fff;
overflow-y: auto;
}
</style>
关于vue.js - 将 shell 输出流式传输到 Web 前端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54725573/