uniapp和vue连接socket

    科技2025-07-30  29

    app.vue全局获取数据并存储在vuex

    app.vue

    <script> // 解压数据 import pako from './hybrid/html/pako.js'; export default { onLaunch: function() { uni.removeStorageSync('showUp') uni.removeStorageSync('rate') uni.removeStorageSync('coin') uni.removeStorageSync('asset') uni.removeStorageSync('deep') uni.removeStorageSync('detail') this.$i18n.locale = uni.getStorageSync('lang')||'zh' // console.log(2222222,uni.getStorageSync('detail')) // console.log(2222222,this.$store.state) this.getRate() this.connect() if (uni.getStorageSync('token')) { this.$store.dispatch('getAsset') } }, onShow: function() { console.log('App Show') }, onHide: function() { console.log('App Hide') }, methods: { connect() { let _this = this uni.connectSocket({ url: 'ws://api.huobiasia.vip/ws', success() { console.log('连接成功1111111111'); _this.getCoin() }, fail() { uni.showToast({ title: '网络连接失败,即将重新连接', icon: 'none' }) _this.connect() }, }); }, // 获取币对信息 getCoin() { let _this = this uni.onSocketOpen((res) => { console.log(1111111111, 'WebSocket连接已打开'); _this.$http('/api/getInstruments').then(data => { let coin; let query1; data.forEach((item, i) => { coin = item.instrument_id.split('-').join('').toLowerCase() _this.$set(item, 'coin', coin) query1 = { sub: "market." + coin + ".depth.step0", id: "id1" } uni.sendSocketMessage({ data: JSON.stringify(query1), success() { uni.onSocketMessage((res) => { let msg = JSON.parse(pako.ungzip(res.data, { to: 'string' })) if (msg.ping) { uni.sendSocketMessage({ data: JSON.stringify({ pang: msg.ping }), }) } else { _this.$store.commit('detail', msg) } }); }, fail(err) { uni.showToast({ title: '发送失败', icon: 'none' }) } }); let query2 = { sub: "market." + coin + ".detail", id: "id1" } uni.sendSocketMessage({ data: JSON.stringify(query2), success() { uni.onSocketMessage((res) => { let msg = JSON.parse(pako.ungzip(res.data, { to: 'string' })) // console.log(msg); if (msg.ping) { uni.sendSocketMessage({ data: JSON.stringify({ pang: msg.ping }), }) } else { _this.$store.commit('detail', msg) } }); } }); }); _this.$store.commit('saveCoin', data) }) }) uni.onSocketError((res) => { console.log(444444, 'WebSocket连接打开失败,请检查!'); _this.connect() }); uni.onSocketClose(function(res) { console.log('WebSocket 已关闭!'); // this.$store.commit('cleardata') _this.connect() }); }, // 获取汇率 getRate() { this.$http('/api/getExchange').then(data => { this.$store.commit('saveRate', parseFloat(data.exchange)) }) }, } } </script> <style> @import './static/iconfont/iconfont.css'; </style> <style lang="scss"> @font-face { font-family: "DIN"; src: url("/common/DIN/DIN-Medium.otf") } .DIN { font-family: 'DIN' !important; } uni-page-body { color: $gray !important; } // 自定义头部,状态栏盒子样式 .status_bar { height: var(--status-bar-height); width: 100%; background-color: #fff; } // tab切换选中加下边框 .active-bb { &::after { content: ''; position: absolute; width: 90%; height: 5rpx; background-color: $blue; left: 5%; bottom: -25rpx; } } // filed .u-field { padding: 26rpx 34rpx !important; .u-label-text { font-weight: 700 !important; } } // 提交按钮 .u-btn--primary { background-color: $blue !important; } .u-size-default { width: 682rpx !important; height: 88rpx !important; font-weight: 700 !important; } // cell组件右边箭头对其文字 .u-cell_title { font-weight: 700 !important; color: #333 !important; } .u-cell__right-icon-wrap { height: 55rpx !important; } /*每个页面公共css */ /* 注意要写在第一行,同时给style标签加入lang="scss"属性 */ @import "uview-ui/index.scss"; @import './common/common.scss'; </style>

    vuex

    import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) import { http } from "../common/http.js" export const store = new Vuex.Store({ state: { userInfo: JSON.parse(localStorage.getItem("userInfo") || "{}"), token: localStorage.getItem("token") || "", rate: localStorage.getItem("rate") || 1, //汇率 coin: JSON.parse(localStorage.getItem("coin") || "[]"), //币值对 asset: localStorage.getItem("asset") == "undefined" ? JSON.parse("{}") : JSON.parse(localStorage.getItem("asset")), //个人资产 lang: localStorage.getItem("lang") || "zh", //语言 deep: JSON.parse(localStorage.getItem("deep") || "{}"), //深度数据 detail: JSON.parse(localStorage.getItem("detail") || "{}"), //详情数据 trade: JSON.parse(localStorage.getItem("trade") || "{}") //实时成交价数据 }, mutations: { // soket深度和详情数据 detail(state, msg) { if (msg.ch) { if (msg.ch.includes('step0')) { state.deep[msg.ch.split('.')[1]] = msg.tick // console.log('深度',state.deep); uni.setStorageSync('deep', state.deep) } else if (msg.ch.includes('detail')) { state.detail[msg.ch.split('.')[1]] = msg.tick // console.log('详情',state.detail); uni.setStorageSync('detail', state.detail) } } // 每次打开app,state中的数据不会清除 // 为了解决后台币种减少的bug,看币值对不包含的币,删除属性 let arr=[]; let key=''; state.coin.forEach(item=>{ arr.push(item.coin) }) Object.keys(state.detail).forEach(item=>{ if(!arr.includes(item)){ key = item } }) delete state.detail[key] }, getUserInfo(state, info) { console.log(); state.userInfo = info state.token = state.userInfo.token uni.setStorageSync('userInfo', state.userInfo) uni.setStorageSync('token', state.userInfo.token) }, savePrint(state, print) { state.print = print uni.setStorageSync('print', print) }, saveLang(state, lang) { state.lang = lang uni.setStorageSync('lang', lang) }, saveRate(state, rate) { state.rate = rate uni.setStorageSync('rate', rate) }, saveCoin(state, coin) { state.coin = coin uni.setStorageSync('coin', coin) }, saveAsset(state, asset) { state.asset = asset uni.setStorageSync('asset', asset) }, exitLogin(state) { state.userInfo = {} state.token = '' uni.setStorageSync('userInfo', state.userInfo) uni.setStorageSync('token', state.userInfo.token) }, }, getters: {}, // this.$store.dispatch('updateUserInfo') actions: { updateUserInfo({ commit }) { http('/api/userInfo').then(data => { commit('getUserInfo', data) }) }, getAsset({ commit }) { if (uni.getStorageSync('token')) { http('/api/funds').then(data => { commit('saveAsset', data) }) } }, } })

    vue中若需要连接连个不同的socket地址,可以创建多个socket对象

    socket.js

    import http from "../js/axios"; import pako from "pako"; import store from "../../store/index"; import vue from "vue"; let ws1; let ws2; export const connect = () => { connect1(); connect2(); }; let connect1 = () => { ws1 = new WebSocket("ws://api.huobiasia.vip/ws"); send1(); }; let connect2 = () => { ws2 = new WebSocket("ws://8.210.219.206:2340"); send2(); }; const send1 = () => { ws1.onopen = function() { // Web Socket 已连接上,使用 send() 方法发送数据 // console.log(111111111, "已连接"); http.get("/api/getInstruments").then(data => { let coin; // eslint-disable-next-line no-unused-vars let query1; let query3; data.forEach(item => { coin = item.instrument_id .split("-") .join("") .toLowerCase(); vue.set(item, "coin", coin); store.commit("saveCoin", data); query1 = { sub: "market." + coin + ".depth.step0", id: "id1" }; query3 = { sub: "market." + coin + ".trade.detail", id: "id1" }; ws1.send(JSON.stringify(query1)); ws1.send(JSON.stringify(query3)); ws1.onmessage = res => { // console.log("blob类型数据: " + res.data); //blob let reader = new FileReader(); reader.readAsArrayBuffer(res.data, "utf-8"); reader.onload = () => { // console.log("blob转ArrayBuffer数据类型", reader.result); // 对数据进行解压 let msg = JSON.parse( pako.ungzip(reader.result, { to: "string" }) ); // console.log("ArrayBuffer转字符串", msg); if (msg.ping) { ws1.send(JSON.stringify({ pang: msg.ping })); } else { store.commit("detail", msg); } }; }; }); }); }; ws1.onclose = function() { // 关闭 websocket console.log("连接已关闭..."); connect1(); }; }; const send2 = () => { ws2.onopen = function() { http.get("/api/getInstruments").then(data => { let query2; // let query3; data.forEach(item => { query2 = "market.subscribe,spot/candle86400s:" + item.instrument_id; ws2.send(query2); ws2.onmessage = data => { if (data.data == "pong") { // ws2.send("ping"); } else { let msg = JSON.parse(data.data); if (msg.market) { store.commit("detail", msg); } } }; }); }); }; ws2.onclose = function() { // 关闭 websocket console.log("连接已关闭..."); connect(); }; }; export const close = () => { ws1.close(); ws2.close(); };

    在main.js引入并调用connect()

    Processed: 0.018, SQL: 8