請教:
建立單列websocket,在不斷開連接的情況下,使用leaveGroup和joinGroup來更換房間。
但是通過Gateway::sendToCurrentClient()「其它發(fā)送方法sendToUid、sendToClient也一樣」發(fā)來的數(shù)據(jù)條數(shù)正好是更換房間的數(shù)量,而且每一條的內(nèi)容完全一樣。
這該如何解決。
客戶端發(fā)送心跳,
sendPing() {
if (this.socket) {
this.socket.send({
data: JSON.stringify({type: 'pong'};),
success: (res) => {
console.log('PingSr:', new Date());
}
});
}
}
服務器回復:
case 'answer': // 服務器回復pong
console.log('srPong!', data);
break;
客戶端leave
socket.send({type: 'leave'});
服務端心跳回復:
case 'pong':
$new_message = array(
'type'=>'answer',
'time'=>date('Y-m-d H:i:s'),
'clients'=>Gateway::getAllClientSessions()
);
Gateway::sendToCurrentClient(json_encode($new_message));
return;
服務端切換房間:
//離開房間
case 'leave':
$room_id = $_SESSION['room_id'];
Gateway::leaveGroup($client_id, $room_id);
return;
//進入房間
case 'join':
$uid = $message_data['uid'];
$room_id = $message_data['room_id'];
$_SESSION['room_id'] = $room_id;
Gateway::joinGroup($client_id, $room_id);
return;
切換多個房間后,微信開發(fā)者工具中竟是這樣:
第一行為客戶端心跳服務器
后面多行為服務端發(fā)來的數(shù)據(jù):條數(shù)與房間數(shù)相同
不知為何,百思不得其姐!
import websocket from './utils/wechat-websocket.js'
//app.js
App({
onLaunch() {
let _this = this;
// 創(chuàng)建websocket對象
this.websocket = new websocket({
// true代表啟用心跳檢測和斷線重連
heartCheck: true,
isReconnection: true
});
// 建立連接
this.linkWebsocket();
// 監(jiān)聽websocket狀態(tài)
this.websocket.onSocketClosed({
url: this.globalData.websocketUrl,
success(res) { console.log(res) },
fail(err) { console.log(err) }
})
// 監(jiān)聽網(wǎng)絡變化
this.websocket.onNetworkChange({
url: this.globalData.websocketUrl,
success(res) { console.log(res) },
fail(err) { console.log(err) }
})
// 監(jiān)聽服務器返回
this.websocket.onReceivedMsg(onMessage => {
console.log('app.js收到服務器內(nèi)容:' + onMessage.data);
// 要進行的操作
var messageData = '';
messageData = JSON.parse(onMessage.data);
//緩存
console.log(messageData);
/*
if (messageData.type == 'init' && messageData.client_id) {
wx.setStorageSync('client_id', messageData.client_id);
}
*/
//反射函數(shù)
if (this.onMessage) {
this.onMessage(messageData);
}
})
},
onHide() {
// 程序后臺后的操作--關閉websocket連接
this.websocket.closeWebSocket();
},
onShow() {
// 程序從后臺到前臺的操作--建立連接
this.linkWebsocket();
},
linkWebsocket() {
// 建立連接
this.websocket.initWebSocket({
url: this.globalData.websocketUrl,
success(res) { console.log(res) },
fail(err) { console.log(err) }
})
},
getWebSocket() {
// 向其他頁面暴露當前websocket連接
return this.websocket;
},
globalData: {
websocketUrl: 'wss://xzb..vip:443/wss',
//websocketUrl: 'ws://127.0.0.1:7272',
baseUrl: 'https://xzb..vip',
//baseUrl: 'http://127.0.0.1:96',
}
})
export default class websocket {
constructor({ heartCheck, isReconnection }) {
// 是否連接
this._isLogin = false;
// 當前網(wǎng)絡狀態(tài)
this._netWork = true;
// 是否人為退出
this._isClosed = false;
// 心跳檢測頻率
this._timeout = 3000;
this._timeoutObj = null;
// 當前重連次數(shù)
this._connectNum = 0;
// 心跳檢測和斷線重連開關,true為啟用,false為關閉
this._heartCheck = heartCheck;
this._isReconnection = isReconnection;
this._onSocketOpened();
}
// 心跳重置
_reset() {
clearTimeout(this._timeoutObj);
return this;
}
// 心跳開始
_start() {
let _this = this;
this._timeoutObj = setInterval(() => {
wx.sendSocketMessage({
// 心跳發(fā)送的信息應由前后端商量后決定
data: JSON.stringify({
uid: wx.getStorageSync('uid')
}),
success(res) {
console.log(res)
console.log("發(fā)送心跳成功");
},
fail(err) {
console.log(err)
_this._reset()
}
});
}, this._timeout);
}
// 監(jiān)聽websocket連接關閉
onSocketClosed(options) {
wx.onSocketClose(err => {
console.log('當前websocket連接已關閉,錯誤信息為:' + JSON.stringify(err));
// 停止心跳連接
if (this._heartCheck) {
this._reset();
}
// 關閉已登錄開關
this._isLogin = false;
// 檢測是否是用戶自己退出小程序
if (!this._isClosed) {
// 進行重連
if (this._isReconnection) {
this._reConnect(options)
}
}
})
}
// 檢測網(wǎng)絡變化
onNetworkChange(options) {
wx.onNetworkStatusChange(res => {
console.log('當前網(wǎng)絡狀態(tài):' + res.isConnected);
if (!this._netWork) {
this._isLogin = false;
// 進行重連
if (this._isReconnection) {
this._reConnect(options)
}
}
})
}
_onSocketOpened() {
wx.onSocketOpen(res => {
console.log('websocket已打開');
// 打開已登錄開關
this._isLogin = true;
// 發(fā)送心跳
if (this._heartCheck) {
this._reset()._start();
}
// 發(fā)送登錄信息
wx.sendSocketMessage({
// 這里是第一次建立連接所發(fā)送的信息,應由前后端商量后決定
data: JSON.stringify({
uid: wx.getStorageSync('uid')
})
})
// 打開網(wǎng)絡開關
this._netWork = true;
})
}
// 接收服務器返回的消息
onReceivedMsg(callBack) {
wx.onSocketMessage(msg => {
if (typeof callBack == "function") {
callBack(msg)
} else {
console.log('參數(shù)的類型必須為函數(shù)')
}
})
}
// 建立websocket連接
initWebSocket(options) {
let _this = this;
if (this._isLogin) {
console.log("您已經(jīng)登錄了");
} else {
// 檢查網(wǎng)絡
wx.getNetworkType({
success(result) {
if (result.networkType != 'none') {
// 開始建立連接
wx.connectSocket({
url: options.url,
success(res) {
if (typeof options.success == "function") {
options.success(res)
} else {
console.log('參數(shù)的類型必須為函數(shù)')
}
},
fail(err) {
if (typeof options.fail == "function") {
options.fail(err)
} else {
console.log('參數(shù)的類型必須為函數(shù)')
}
}
})
} else {
console.log('網(wǎng)絡已斷開');
_this._netWork = false;
// 網(wǎng)絡斷開后顯示model
wx.showModal({
title: '網(wǎng)絡錯誤',
content: '請重新打開網(wǎng)絡',
showCancel: false,
success: function (res) {
if (res.confirm) {
console.log('用戶點擊確定')
}
}
})
}
}
})
}
}
// 發(fā)送websocket消息
sendWebSocketMsg(options) {
wx.sendSocketMessage({
data: options.data,
success(res) {
if (typeof options.success == "function") {
options.success(res)
} else {
console.log('參數(shù)的類型必須為函數(shù)')
}
},
fail(err) {
if (typeof options.fail == "function") {
options.fail(err)
} else {
console.log('參數(shù)的類型必須為函數(shù)')
}
}
})
}
// 重連方法,會根據(jù)時間頻率越來越慢
_reConnect(options) {
let timer, _this = this;
if (this._connectNum < 20) {
timer = setTimeout(() => {
this.initWebSocket(options)
}, 3000)
this._connectNum += 1;
} else if (this._connectNum < 50) {
timer = setTimeout(() => {
this.initWebSocket(options)
}, 10000)
this._connectNum += 1;
} else {
timer = setTimeout(() => {
this.initWebSocket(options)
}, 450000)
this._connectNum += 1;
}
}
// 關閉websocket連接
closeWebSocket() {
wx.closeSocket();
this._isClosed = true;
}
}