vue与go后端的websocket连接

vue端:

<template>
  <div class="home">
    <div class="home-header">
      <el-row style="margin: 0">
        <el-col :span="8" :offset="4">
          <div class="home-header-search">
            <p class="header-search-title">XXXXXXX</p>
            <p class="header-search-subtitle">XXXXXXXXXX</p>
            <el-input
              class="header-search-input"
              v-model="searchInput"
              prefix-icon="el-icon-search"
              placeholder="用户ID/存证HASH/TX哈希/区块高度/区块哈希"
            />
          </div>
        </el-col>
        <el-col :span="8" class="home-header-image">
          <img src="../assets/images/header/banner-image.png" />
        </el-col>
      </el-row>
    </div>
    <div class="home-main">
      <div class="home-card">
        <el-row :gutter="20">
          <el-col :span="4" :offset="4">
            <el-card shadow="always">
              <p>区块数量</p>
              <p class="info-card-content">{{ wsData["blocksCount"] }}</p>
            </el-card>
          </el-col>
          <el-col :span="4">
            <el-card shadow="always">
              <p>交易数量</p>
              <p class="info-card-content">{{ wsData["transactionsCount"] }}</p>
            </el-card>
          </el-col>
          <el-col :span="4">
            <el-card shadow="always">
              <p>账户数量</p>
              <p class="info-card-content">{{ wsData["accountsCount"] }}</p>
            </el-card>
          </el-col>
          <el-col :span="4">
            <el-card shadow="always">
              <p>存证数量</p>
              <p class="info-card-content">{{ wsData["evidenceCount"] }}</p>
            </el-card>
          </el-col>
        </el-row>
      </div>

      <el-row class="home-list">
        <el-col :span="16" :offset="4" class="info-detail blcoks-list">
          <div class="bs-callout bs-callout-primary">
            <span class="bs-callout-title">区块</span>
            <span class="bs-callout-sub-title">最新产生的区块</span>
            <router-link to="/blocks" class="bs-callout-sub-more"
              >查看更多</router-link
            >
          </div>
          <tl-table :table="blockList"></tl-table>
        </el-col>
        <el-col :span="16" :offset="4" class="info-detail transactions-list">
          <div class="bs-callout bs-callout-primary">
            <span class="bs-callout-title">交易</span>
            <span class="bs-callout-sub-title">最新产生的交易</span>
            <router-link to="/transactions" class="bs-callout-sub-more"
              >查看更多</router-link
            >
          </div>
          <tl-table :table="transactionList" @onRowClick="rowClick"></tl-table>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import tlTable from "../components/recordlist.vue";

export default {
  name: "home",
  components: {
    tlTable
  },
  data() {
    return {
      searchInput: "",
      websock: null,
      wsData: {
        blocksCount: 0,
        transactionsCount: 0,
        accountsCount: 0,
        evidenceCount: 0
      },
      infoData: {},
      blockList: {
        loading: true,
        tr: [
          {
            id: "1",
            label: "区块高度",
            prop: "block_num",
            // show: 'template',
            width: "100",
            className: "username"
          },
          {
            id: "2",
            label: "区块哈希",
            prop: "block_id",
            minWidth: 140
          },
          {
            id: "3",
            label: "TX数",
            minWidth: "20",
            prop: "block.transactions.length"
          },
          {
            id: "4",
            label: "出块时间",
            prop: "createdAt"
          },
          {
            id: "5",
            label: "出块节点",
            prop: "block.producer"
          }
        ],
        data: []
      },
      transactionList: {
        loading: true,
        tr: [
          {
            id: "1",
            label: "交易序号",
            prop: "block_num",
            width: "100",
            // show: 'template',
            className: "username"
          },
          {
            id: "2",
            label: "交易hash",
            prop: "id"
          },
          {
            id: "4",
            label: "出块时间",
            prop: "createdAt"
          }
        ],
        data: []
      }
    };
  },
  methods: {
    rowClick(row) {
      this.$router.push({
        path: "/transactions/transactionDetail/" + row["row"]["id"]
      });
    },
    initWebSocket() {
      // 初始化weosocket
      const wsuri = "ws://111.111.111.111:0000/ws";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
      s;
    },
    websocketonopen() {
      // 连接建立之后执行send方法发送数据
      let actions = { event: "home" };
      this.websocketsend(JSON.stringify(actions));
    },
    websocketonerror() {
      // 连接建立失败重连
      this.initWebSocket();
    },
    websocketonmessage(data) {
      // 数据接收
      const wsData = JSON.parse(data.data);
      if (wsData["event"] === "home") {
        this.wsData = wsData.data;
      }
    },
    websocketsend(Data) {
      // 数据发送
      this.websock.send(Data);
    },
    websocketclose(e) {
      // 关闭
      console.log("断开连接", e);
    }
  },
  watch: {
    wsData(val, oldVal) {
      this.blockList.data = val["blockList"];
      this.transactionList.data = val["transactionList"];
      // this.infoData = val['info'];
    },
    "blockList.data": function(val) {
      this.blockList.loading = false;
    },
    "transactionList.data": function(val) {
      this.transactionList.loading = false;
    }
  },
  beforeCreate() {
    // 获取路由路径
    sessionStorage.setItem("headerIndex", this.$route.path);
  },
  mounted() {
    if (!this.websock) {
      this.initWebSocket();
    }
  },
  updated() {
    // this.blockList.data = this.wsData['blockList'];
  },
  beforeDestroy() {
    this.websock.close();
  }
};
</script>

<style lang="less">
.header-search-input {
  .el-input__inner {
    border-radius: 20px;
  }
}
</style>

<style scoped lang="less">
@import "../assets/css/wrapper";

.home {
  .home-header {
    min-height: 500px;
    background: url("../assets/images/header/banner1.png") no-repeat;
    background-size: cover;
    .home-header-search {
      color: #fff;
      margin: 20% 0 100px 0;
      .header-search-title {
        font-size: 2.5em;
      }
      .header-search-subtitle {
        font-size: 24px;
      }
      .header-search-input {
        width: 80%;
      }
    }
    .home-header-image {
      /*padding-top: 120px;*/
      img {
        margin-top: 20%;
      }
    }
  }

  .home-main {
    .home-card {
      margin: 30px 10px;
      font-weight: bold;
      .info-card-content {
        font-size: 20px;
        color: rgb(64, 158, 255);
      }
    }
    .home-list {
      margin: 0;
      .info-detail {
        margin-top: 10px;
        margin-bottom: 30px;
      }
    }
  }
}
</style>

 beego后端:

package routers

import (
	"monitorServer/controllers"
	"github.com/astaxie/beego"
)

func init() {
    beego.Router("/", &controllers.MainController{})
    beego.Router("/ws", &controllers.MyWebSocketController{})
}





package controllers

import (
	"github.com/astaxie/beego"
	"github.com/gorilla/websocket"
	"log"
	"monitorServer/models"
	"time"
)

type MyWebSocketController struct {
	beego.Controller
}

// 配置 upgrader
var upgrader = websocket.Upgrader{}

func (c *MyWebSocketController) Get() {
	// 将初始GET请求升级到websocket
	ws, err := upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil)
	if err != nil {
		log.Fatal(err)
	}
	// 返回时关闭连接
	defer ws.Close()

	// 将新的客户端连接添加到字典中
	clients[ws] = true

	//不断的广播发送到页面上
	for {
		//目前存在问题 定时效果不好 需要在业务代码替换时改为beego toolbox中的定时器
		time.Sleep(time.Second * 3)
		msg := models.Message{Message: "这是向页面发送的数据 " + time.Now().Format("2006-01-02 15:04:05")}
		broadcast <- msg
	}
}






package controllers

import (
	"monitorServer/models"
	"log"
	"github.com/gorilla/websocket"
)

// 使用字典结构更容易追加和删除内容
var (
	clients   = make(map[*websocket.Conn]bool)  // 保存连接的客户端
	broadcast = make(chan models.Message)  // 消息广播通道
)

func init() {
	go handleMessages()
}

// 发送
func handleMessages() {
	for {
		msg := <-broadcast
		// 将其发送给当前连接的每个客户端
		if len(clients) != 0 {
			for client := range clients {
				err := client.WriteJSON(msg)
				if err != nil {
					log.Printf("client.WriteJSON error: %v", err)
					client.Close()
					delete(clients, client)
				}
			}
		}
	}
}





package models

type Message struct {
    Message string `json:"message"`
}

参考:

https://www.jianshu.com/p/5284d4336a7c

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值