前端vue连接websocket

封装websocket的Api

/* eslint-disable no-mixed-spaces-and-tabs */
/*------------------------- web socket方法封装 -------------------------*/
    /*连接websocket*/
    var ws;
    var port = '0'; //前一次端口号,断线重连时用到
    var seq=0;//第几次请求握手
    export const websocketFun = (parmas) => {
        var WebSocketsExist = true;
	    try {
	        ws = new WebSocket("ws://" + parmas.websocketip + ":" + parmas.websocketport);
	    }
	    catch (ex) {
	        try {
	            ws = new WebSocket("ws://" + this.$store.state.websocketip + ":" + this.$store.state.websocketport);
	        }
	        catch (ex) {
	            WebSocketsExist = false;
	        }
	    }
	    if (!WebSocketsExist) {
	        return;
	    }
	    ws.onopen = WSonOpen;
	    //ws.onmessage = WSonMessage;
	    ws.onclose = WSonClose;
        ws.onerror = WSonError;
        return ws; 
      }

    function WSonOpen() {
        var json={};
		json.userid=sessionStorage.getItem("userId");
		json.username=sessionStorage.getItem("username");
        json.FSNo="01";
        json.svrtype="8";
        json.msgType="msg_HandShake";
        json.port=port;
        json.reportflag="1";
        json.format="0";
        json.seq=seq;
        seq++;
        let str = JSON.stringify(json);
        let length=str.length;
        let len=length.toString(16);
        len=len.padStart(4, "0"); 
        str=len+str;
        ws.send(str);
   }

function WSonClose() {
}

function WSonError() {
}

使用(我自己的案例)

<template>
  <div class="meterSwitch">
    <div class="header">
      <div class="search">
        <el-form size="mini" :inline="true" :model="search" class="demo-form-inline">
          <el-form-item label="户号">
            <el-input v-model="search.customerNum"></el-input>
          </el-form-item>
          <el-form-item label="户名">
            <el-input v-model="search.customerName"></el-input>
          </el-form-item>
          <el-form-item label="电表地址">
            <el-input v-model="search.meterAddress"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button icon="el-icon-search" size="mini" type="primary" @click="getMeterSwitchList">查询</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="Newly">
        <el-button icon="el-icon-connection" size="mini" type="primary" @click="readingSelect">透抄</el-button>
      </div>
    </div>
    <div class="content">
      <el-table
        :data="tableData"
        border
        style="width: 100%"
        height="100%"
        ref="multipleTable"
        tooltip-effect="dark"
        @selection-change="handleSelectionChange"
      >
        <el-table-column align="center" type="selection" width="55"></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="电表ID"
          prop="fileId"
          v-if="false"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="集中器ID"
          prop="upGoingId"
          v-if="false"
        ></el-table-column>
        <!-- <el-table-column type="index" width="50" prop="index"></el-table-column> -->
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="120"
          label="户名"
          prop="customerName"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="120"
          label="户号"
          prop="customerNum"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="电表地址"
          prop="meterAddress"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          label="安装地址"
          prop="installAddress"
        ></el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          prop="readingStatus"
          label="透抄结果"
        >
          <template slot-scope="scope">
            <span v-if="scope.row.readingStatus==1" style="color: green">成功</span>
            <span v-else-if="scope.row.readingStatus==0" style="color: red">失败</span>
            <span v-else style="color: black">未透抄</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          :show-overflow-tooltip="true"
          width="150"
          label="数据内容"
          prop="readingData"
        ></el-table-column>
      </el-table>
    </div>
    <!-- 分页 -->
    <div class="block">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="search.page"
        :page-sizes="pages"
        :page-size="search.size"
        layout="total,sizes, prev, pager, next, jumper"
        :total="params.total"
      ></el-pagination>
    </div>
  </div>
</template>

<script>
import { websocketFun } from "@/request/websocketApi";
import { getMeterSwitchList, openSwitch } from "@/request/meterapi";
export default {
  data() {
    return {
      ws: "",
      search: {
        page: 1,
        size: 10,
        meterAddress: "",
        customerName: "",
        customerNum: "",
        organizationid: "",
        gid: "",
        type:'',
      },
      // 分页
      pages: [10, 20, 40],
      tableData: [],
      exchangeTableData: [],
      params: {
        total: 0
      },
      dealRows: [],
      multipleSelection: []
    };
  },
  computed:{
    tree(){
      return this.$store.state.tree
    }
  },
  watch: {
    tree:{
      deep:true,//代表深层次的监听
      immediate:true,//页面初始化的时候就立即触发一次
      handler(val){
        // console.log('vuex树',val)
        if(val.type===3){
          this.search.meterAddress = val.name
        }else {
          this.search.meterAddress = ''
        }
        if(val.type===2){
          this.search.customerName = val.name
          this.search.gid = val.gid
          this.search.type = val.type
        }else {
          this.search.customerName = ''
        }
        if(val.type===1){
          this.search.gid = val.gid
          this.search.type = val.type
        }
        // console.log('this.search---',this.search)
        this.page = 1
        this.getMeterSwitchList();
      }
    }
  },
  methods: {
    getMeterSwitchList() {
      getMeterSwitchList(this.search).then(res => {
        this.tableData = res.data.data;
        this.params.total = res.data.total;
      });
      if (this.ws == "") {
        this.ws = websocketFun(this.$store.state);
        this.ws.onmessage = this.WSonMessage;
      }
    },
    WSonMessage(event) {
      if (!event) {
        return;
      }
      let str = event.data; //要截取的字符串
      let index = str.indexOf("{");
      let result = str.substr(index, str.length);
      let events = eval("(" + result + ")");
      if (events.result == "nak") {
        this.$message({
          message: "与前置机连接被拒绝!",
          type: "error",
          duration: 3000
        });
      } else if (events.result == "ack") {
        console.log("与前置机连接成功!");
      } else {
        console.log(events);
        if (events.errorCode == "ok") {
          this.$message({
            message: "操作成功!",
            type: "success",
            duration: 3000
          });
          //同时修改数据库里电表下达状态,关于电表的数据在events.objJson里,
          //还需解析,然后根据电表地址 判断index,将数据写入到对应的列
          // this.tableData[this.dealRow].readingStatus=1;
          // this.tableData[this.dealRow].readingData=events.objJson;
        } else if (events.errorCode == "notOnline") {
          this.$message({
            message: "操作失败,集中器不在线!",
            type: "error",
            duration: 3000
          });
          //同时修改数据库里电表下达状态,关于电表的数据在events.objJson里,
          //还需解析,然后根据电表地址 判断index,将数据写入到对应的行
          //events.objJson.forEach((val) => {
          this.multipleSelection.forEach(val => {
            this.tableData.forEach((v, i) => {
              if (val.fileId == v.fileId) {
                this.dealRows.push(i);
              }
            });
          });
          this.$refs.multipleTable.clearSelection();
          for (let dealRow of this.dealRows) {
            this.tableData[dealRow].readingStatus = 0;
            this.tableData[dealRow].readingData = events.objJson;
          }
          this.dealRows = [];
        } else if (events.errorCode == "failed") {
          this.$message({
            message: "操作失败!",
            type: "error",
            duration: 3000
          });
        } else {
          this.$message({
            message: events,
            type: "error",
            duration: 3000
          });
        }
      }
    },
    handleCurrentChange(val) {
      this.search.page = val;
      this.getMeterSwitchList();
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.search.page = 1;
      this.getMeterSwitchList();
    },
    readingSelect() {
      if (this.multipleSelection.length == 0) {
        this.$message({
          message: "请勾选后操作!",
          type: "warning",
          duration: 2000
        });
      }
      if (this.ws.readyState == 1) {
        for (let select of this.multipleSelection) {
          let electricmeter = {};
          electricmeter.fileId = select.fileId;
          electricmeter.upGoingId = select.upGoingId;
          openSwitch(electricmeter).then(res => {
            let openSwitchStr = res.data.data;
            this.ws.send(openSwitchStr);
            console.log("已发送");
          });
        }
      } else {
        this.$message({
          message: "未连接前置机!",
          type: "warning",
          duration: 2000
        });
      }
      console.log(this.multipleSelection);
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    }
  },
  created() {
    this.getMeterSwitchList();
  }
};
</script>

<style lang="scss">
.meterSwitch {
  height: 100%;
  .header {
    vertical-align: middle;
    .search {
      // display: inline-block;
      vertical-align: top;
    }
    .Newly {
      display: block;
    }
  }
  .content {
    height: calc(100% - 120px);
    margin-top: 10px;
    .el-form-item {
      width: 33% !important;
    }
    .demo-table-expand {
      font-size: 0;
    }
    .el-form-item__label {
      // width: 90px;
      color: #99a9bf !important;
    }
    .demo-table-expand .el-form-item {
      margin-right: 0;
      margin-bottom: 0;
      width: 50%;
    }
  }
}
</style>

使用vuex保存连接websocket的ip、端口等信息

1、安装vuex

import vuex from 'vuex'

2、在main.js里把vuex注册到vue全局组件里

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import store from './store/index.js'
import Vuex from 'vuex'

Vue.use(ElementUI)
Vue.use(Vuex)//使用vuex
Vue.config.productionTip = false
import './assets/font/iconfont.css'
// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
// 引入reset.css
import './assets/css/reset.css'
import './assets/css/base.css'

state: {
    websocketip:"193.168.1.100",
    websocketport:"20020",
  },
var store = new vuex.Store({//创建vuex中的store对象
    state
})

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

你可能感兴趣的:(vue相关)