首页 > 分享 > Golang+Vue2从零开始搭建K8S后台管理系统(4)——自动更新资源列表(下)

Golang+Vue2从零开始搭建K8S后台管理系统(4)——自动更新资源列表(下)

目录

梗概

基本做法

实操部分

后端实现

前端websocket客户端

总结

梗概

上章实现了后端deployment map的实时更新,我们还需要把这部分的更新传送到前端。

本章重点讲述前后端通过websocket进行这部分的数据交互。

基本做法

基本思路是,当前端请求后端列表api时,同时发送另一个http请求到后端,根据websocket的原理,可以将该连接升级成websocket连接。我们将这个客户端存到一个本地缓存维护的map中,当资源发生变动,触发handler,我们同样将更新后的列表发送到前端,前端更新用于列表展示的那部分数据。

实操部分

后端实现

首先定义接口,http升级websocket,并将客户端保存在map里面

func Connect(c *gin.Context) string {

client,_ := websocket.Upgrader{}.Upgrade(c.Writer, c.Request, nil)

wscore.ClientMap.Store(client)

return "true"

}

其中,ClientMap是定义好的一个全局对象,供所有需要使用websocket的handler使用

var ClientMap *ClientMapStruct

type ClientMapStruct struct {

data sync.Map

lock sync.Mutex

}

那么,针对前步中升级websocket获得的连接对象,我们需要有以下操作:

1.存入到map中

this.data.Store(conn.RemoteAddr().String(), wsClient)

2.开启协程定时发送消息检测存活,ping一下,出错就从map中删除这个连接,这是比较初级的做法。

func (this *WsClient) Ping(waittime time.Duration) {

for {

time.Sleep(waittime)

func() {

this.Locker.Lock()

defer this.Locker.Unlock()

err := this.conn.WriteMessage(websocket.TextMessage, []byte("ping"))

if err != nil {

ClientMap.Remove(this.conn)

return

}

}()

}

}

这里定义了一个结构体,并加入了sync.Mutex。因为websocket不支持并发写,所以加入互斥锁。

题外话,其实websocket也会存在客户端继续压入数据的情况。对此,需要开启一个协程,反复(死循环)从连接中读取信息,并推入这部分信息到channel中。再另外开启一个协程去处理 总控 循环。这样是比较合理的做法,这与我们要实现的功能无关,所以不做过多的演示。

然后,我们需要实现一个传参为interface{}的方法去接受一个对象,并把这部分的对象数据给发送到所有的客户端,客户端判断数据是否和我需要的类型相匹配,(如果匹配)做对应更新。这同样是比较初级的做法,有如下。

func (this *ClientMapStruct) SendAll(v interface{}) {

this.data.Range(func(key, value any) bool {

func() {

c := value.(*WsClient).conn

value.(*WsClient).Locker.Lock()

defer value.(*WsClient).Locker.Unlock()

err := c.WriteJSON(v)

if err != nil {

this.Remove(c)

log.Println(err)

}

}()

return true

})

}

然后在informer-handler中调用该接口,包括了新增、删除、更新,下面是一个示例。

func (this *DepHandler) OnAdd(obj interface{}) {

this.DepMap.Add(obj.(*v1.Deployment))

ns := obj.(*v1.Deployment).Namespace

wscore.ClientMap.SendAll(gin.H{

"type": "deployment",

"result": gin.H{

"ns": ns,

"data": this.DepService.ListAll(ns),

},

})

}

至此,后端的websocket改造已实现。

接下来我们看前端。

前端websocket客户端

首先引入js中websocket客户端的实现:

let lock=false;

let wsClient;

function reConnect() {

if (lock) return;

lock = true;

console.log("正在重连")

setTimeout(function() {

NewClient();

lock = false;

}, 2000);

}

const GetClient=function () {

if(wsClient!=null && wsClient.readyState===1){

return wsClient

}

NewClient()

return wsClient

}

const NewClient=function () {

wsClient = new WebSocket("ws://localhost:8080/ws");

wsClient.onopen = function(){

console.log("open");

}

wsClient.onclose = function(e){

console.log("close");

reConnect()

}

wsClient.onerror = function(e){

console.log(e);

reConnect()

}

return wsClient

}

export {NewClient}

 其中,指定了后端http的接口,后端在接受这个请求后会将连接升级成websocket。

然后在列表组件中引入

import { NewClient } from '@/utils/ws'

接着在create函数中调用websocket客户端:

export default {

data() {

return {

list: null,

listLoading: true,

wsClient: null,

}

},

created() {

this.fetchData()

},

methods: {

fetchData() {

this.listLoading = true

this.wsClient = NewClient()

this.wsClient.onmessage=(e)=>{

if (e.data !== 'ping') {

const obj = JSON.parse(e.data)

if (obj.type === 'deployment') {

this.list = obj.result.data

this.$forceUpdate()

}

}

}

},

}

}

</script>

 其中,消息内容为ping的用于探活的测试数据会被drop掉,判断类型为‘deployment’的数据则会被更新到data中。要注意的是,列表数据的更新必须调用forceUpdate来进行重新渲染。

总结

至此,整一个websocket的前后端调用就完成了。可见的是,这种是比较初级的做法,未来将会看见更优雅的实现。

相关知识

Vue.js 增删查改库存管理系统教程:新手友好的完整代码与详细步骤」 「从零开始的库存管理系统:Vue.js 实现搜索、编辑、删除与数据更新」 「超详细的 Vue.js CRUD 教程:带你一步步构
K8s系列 Prometheus+Grafana构建智能化监控系统
Vue.js实战:从零开始构建花店管理系统
花店在线购物管理资源
HTML+CSS+JavaScript美食博客网页制作教程:从零开始,超详细代码解析与完整示例,适合初学者!
Java项目源码javaweb花店销售管理系统
进销存系统开发,库存管理系统定制,仓库管理平台搭建,企业erp管理网站制作【最新版】
聚合支付系统平台搭建
基于python的在线花店管理系统
花店系统花点的网站资源

网址: Golang+Vue2从零开始搭建K8S后台管理系统(4)——自动更新资源列表(下) https://m.huajiangbk.com/newsview949134.html

所属分类:花卉
上一篇: 高效搭建后台系统的解决方案
下一篇: 外卖分销返佣分佣程序外卖cps小