(精華2020年5月21日更新) vue實戰篇 實時通訊websocket的封裝結合vue的使用
import webSocket from '../webSocket.js';
export default {
isIosAndroid() {
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android終端
isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios終端
isChrome = u.indexOf('Safari'); //瀏覽器端
return {
isAndroid,
isiOS,
isChrome
}
},
websocktSend(paramsObj) {
// this --> store
//這個是用來向後端websocket傳送資訊,傳送之前需要先判斷是否還處理連結狀態
var userId = localStorage.getItem('userId');
var sendMsg = () => {
window.socketServer.send(JSON.stringify(paramsObj)); //給後端傳送資訊
}
if (window.socketServer.readyState == 1) {
sendMsg();
} else {
// 這裡的this是$store,傳遞進來的
// 這個this你並不知道
webSocket.call(this, wsconPath[sceneParam] + userId).then(() => {
sendMsg();
});
}
},
// 時間顯示的幾分鐘、幾小時、當天、昨天、前天以及更早的具體時間
// 2019-12-07 09:58:23
// JS計算兩個日期時間差,天 小時 分 秒格式
showDiffTime: function (startDate) {
if (!startDate) {
return;
}
var startDate = startDate.replace(new RegExp(/-/gm), "/");
var startDateB = new Date(startDate);
var updateHour = startDateB.getHours(),
updateMin = startDateB.getMinutes();
updateHour = updateHour < 10 ? '0' + updateHour : updateHour;
updateMin = updateMin < 10 ? '0' + updateMin : updateMin;
var endDate = new Date(); //現在的時間
var diff = endDate.getTime() - startDateB.getTime(); //時間差的毫秒數
//計算出相差天數
var days = Math.floor(diff / (24 * 3600 * 1000));
// 1.當天,顯示:HH:MM
// 2.昨天,顯示:昨天 HH:MM
// 3.前天,顯示:前天 HH:MM
// 4.更早,顯示:****年**月**日 HH:MM
if (days > 0) {
if (days == 1) {
return "昨天 " + updateHour + ':' + updateMin;
}
if (days == 2) {
return "前天 " + updateHour + ':' + updateMin;
}
if (days > 2) {
return startDate.split(' ')[0] + ' ' + updateHour + ':' + updateMin;
}
}
if (days == 0) {
return updateHour + ':' + updateMin;
}
},
// 像scroll,resize,keyup scroll等事件頻繁觸發會引發頁面的抖動甚至卡頓
debounce(fn, delay) {
delay = delay || 200;
var timer = null;
return function () {
var arg = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(this, arg);
}, delay);
}
},
}
//心跳檢測
var heartCheck = {
timeout: 3000, //每隔三秒傳送心跳
// num: 3, //3次心跳均未響應重連
timeoutObj: null,
reset: function(){//接收成功一次推送,就將心跳檢測的倒數計時重置為30秒
clearTimeout(this.timeoutObj);//重置倒數計時
this.start();
},
start: function(){
//啟動心跳檢測機制,設定倒數計時30秒一次
this.timeoutObj = setTimeout(function(){
//這裡傳送一個心跳,後端收到後,返回一個心跳訊息,
//onmessage拿到返回的心跳就說明連線正常
var userId = localStorage.getItem('userId');
if(!userId){
return;
}
window.socketServer.send(JSON.stringify({
photographerObjectId:'',
type:'6',
leavingContent:'',
photographerId:userId //留言攝影師編號
})); //給後端傳送資訊
},this.timeout)
}
//onopen連線上,就開始start及時,如果在定時時間範圍內,onmessage獲取到了服務端訊息,
//就重置reset倒數計時,距離上次從後端獲取訊息30秒後,執行心跳檢測,看是不是斷了。
}
/**建立連線 */
function createWSConnect(path){
var _store = this;
if (typeof WebSocket === "undefined") {
alert("您的瀏覽器不支援socket");
} else {
return new Promise((resolve,reject)=>{
// 例項化socket
var socket = new WebSocket(path);
// 監聽socket連線
socket.onopen = function(){
console.log("socket連線成功!!!");
window.socketServer = socket;
resolve(socket);
//要不要把socket存放在store呢,看自己
//心跳檢測啟動
heartCheck.start();
};
socket.onclose = function (e) {
console.log('websocket 斷開: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
console.log(e);
reconnect(path);
}
// 監聽socket錯誤資訊
socket.onerror = function(){
socket.close();
reject();
console.log("連線錯誤");
reconnect(path);
};
// 監聽socket訊息,後端給到前端的資料
socket.onmessage = function(res){
if(res.data==1){
//檢測心跳
heartCheck.reset();
return;
}
var data = res.data && JSON.parse(res.data);
// _store.dispatch('UpdateChatBadge',{count:data.count})
updateMsgForType.call(_store,data);
};
})
}
}
//重新建立連結
reconnect.lockReconnect = false;//避免重複連線
reconnect.timer = '';
function reconnect(url) {
if (reconnect.lockReconnect) return;
reconnect.lockReconnect = true;
reconnect.timer && clearTimeout(reconnect.timer);
//沒連線上會一直重連,設定延遲避免請求過多
reconnect.timer = setTimeout(function () {
createWSConnect(url);
reconnect.lockReconnect = false;
}, 4000);
}
function updateMsgForType(data){
if(data.error){
this.$Toast(data.error);
return;
}
this.dispatch('UpdateChatBadge',{count:data.count})
switch(data.type){
case '0': // 0 一對一交流文字
this.dispatch('communication/addOneToOne',data.siteComm)
break;
case '1': //1 一對一交流圖片
this.dispatch('communication/addOneToOne',data.siteComm)
break;
case '2': //2 未讀總條數
break;
case '3': //撤回被刪除的資訊
this.dispatch('communication/withdrawOneToOne',{count:data.siteComm})
break;
case '4': //單條代表刪除一對一資訊
this.dispatch('communication/delOneToOne',data.siteComm)
break;
case '5': //批量刪除一對一資訊
this.dispatch('communication/delAllOneToOne',data.siteComm)
break;
}
}
export default createWSConnect;
vue頁面的使用
utils.websocktSend.call(this.$store, paramsObj);
相關文章
- vue websocket nodeJS 進行實時通訊踩到的坑VueWebNodeJS
- 在vue中使用SockJS實現webSocket通訊VueJSWeb
- (精華2020年5月17日更新) vue實戰篇 手寫vue底層原始碼Vue原始碼
- (精華2020年5月8日更新) vue教程篇 vue-router路由的使用Vue路由
- ai問答:vue3+pinia+WebSocket 封裝斷線重連(實戰)AIVueWeb封裝
- Uniapp 使用 GoEasy 實現 websocket 實時通訊APPGoWeb
- Vue Axios 的封裝使用VueiOS封裝
- Vue3實戰系列:結合 Ant-Design-of-Vue 實踐 Composition APIVueAPI
- vue中使用axios的封裝VueiOS封裝
- 即時通訊技術文集(第14期):WebSocket精華文章合集 [共15篇]Web
- 使用Java實現WebSocket通訊JavaWeb
- (精華2020年5月4日更新) vue教程篇 計算屬性computed的使用Vue
- (精華2020年5月8日更新) vue教程篇 vue-router路由的許可權控制Vue路由
- vue中axios的使用與封裝VueiOS封裝
- (精華2020年5月4日更新) vue教程篇 簡單小結(1)-使用者管理Vue
- (精華2020年6月24日更新)asp.net core3.1實戰篇 RabbitMQ的使用一(安裝Erlang)ASP.NETMQ
- (精華2020年5月4日更新) vue教程篇 v-show和v-if的使用Vue
- 「Vue實戰」武裝你的專案Vue
- Ladda的vue封裝Vue封裝
- 在Spring Boot中實現WebSocket實時通訊Spring BootWeb
- 從0到1使用VUE-CLI3開發實戰(四): Axios封裝VueiOS封裝
- ts結合vue使用的感悟Vue
- Electron-vue開發實戰4——通過CI釋出以及更新的方式Vue
- WebSocket 封裝,vue3專案 拿來即用Web封裝Vue
- websocket使用(vue)WebVue
- vue中Axios的封裝和API介面的管理(更新)VueiOS封裝API
- eventBus(封裝) 一個巧妙的解決vue同級元件通訊的思路封裝Vue元件
- 封裝Vue 的 SVG 元件封裝VueSVG元件
- Vue 基礎篇(一):Vue元件間通訊Vue元件
- 基於vue.js實現樹形表格的封裝Vue.js封裝
- Vue元件通訊中eventBus的使用Vue元件
- Vue 實戰專案:koa+typescript+MySQL+Vue+socket.io 搭建即時通訊 IM 伺服器及 UIVueTypeScriptMySql伺服器UI
- Vue知識精簡總結-更新中Vue
- 細談 vue - 抽象元件實戰篇Vue抽象元件
- Vue 元件的通訊Vue元件
- laravel整合workerman實現websocket多端及時通訊LaravelWeb
- Vue+WebSocket 實現頁面實時重新整理長連線VueWeb
- Vue結合uniapp實現水平公告欄VueAPP