前端vue连接websocket

    技术2022-07-10  129

    封装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')
    Processed: 0.010, SQL: 9