Browse Source

websocket reconnect

master
tangmingyou 3 years ago
parent
commit
acaabe1dd9
  1. 183
      src/api/proto.js
  2. 135
      src/api/websocket.js
  3. 3
      src/pages/login/login.jsx
  4. 13
      src/store/conn.js

183
src/api/proto.js

@ -26,6 +26,7 @@ export const api = $root.api = (() => {
* @property {number|null} [op] ProtoWrap op
* @property {number|null} [seq] ProtoWrap seq
* @property {boolean|null} [success] ProtoWrap success
* @property {number|Long|null} [reqMs] ProtoWrap reqMs
* @property {Uint8Array|null} [body] ProtoWrap body
*/
@ -76,6 +77,14 @@ export const api = $root.api = (() => {
*/
ProtoWrap.prototype.success = false;
/**
* ProtoWrap reqMs.
* @member {number|Long} reqMs
* @memberof api.ProtoWrap
* @instance
*/
ProtoWrap.prototype.reqMs = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* ProtoWrap body.
* @member {Uint8Array} body
@ -116,6 +125,8 @@ export const api = $root.api = (() => {
writer.uint32(/* id 3, wireType 0 =*/24).int32(message.seq);
if (message.success != null && Object.hasOwnProperty.call(message, "success"))
writer.uint32(/* id 4, wireType 0 =*/32).bool(message.success);
if (message.reqMs != null && Object.hasOwnProperty.call(message, "reqMs"))
writer.uint32(/* id 5, wireType 0 =*/40).int64(message.reqMs);
if (message.body != null && Object.hasOwnProperty.call(message, "body"))
writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.body);
return writer;
@ -168,6 +179,10 @@ export const api = $root.api = (() => {
message.success = reader.bool();
break;
}
case 5: {
message.reqMs = reader.int64();
break;
}
case 7: {
message.body = reader.bytes();
break;
@ -219,6 +234,9 @@ export const api = $root.api = (() => {
if (message.success != null && message.hasOwnProperty("success"))
if (typeof message.success !== "boolean")
return "success: boolean expected";
if (message.reqMs != null && message.hasOwnProperty("reqMs"))
if (!$util.isInteger(message.reqMs) && !(message.reqMs && $util.isInteger(message.reqMs.low) && $util.isInteger(message.reqMs.high)))
return "reqMs: integer|Long expected";
if (message.body != null && message.hasOwnProperty("body"))
if (!(message.body && typeof message.body.length === "number" || $util.isString(message.body)))
return "body: buffer expected";
@ -245,6 +263,15 @@ export const api = $root.api = (() => {
message.seq = object.seq | 0;
if (object.success != null)
message.success = Boolean(object.success);
if (object.reqMs != null)
if ($util.Long)
(message.reqMs = $util.Long.fromValue(object.reqMs)).unsigned = false;
else if (typeof object.reqMs === "string")
message.reqMs = parseInt(object.reqMs, 10);
else if (typeof object.reqMs === "number")
message.reqMs = object.reqMs;
else if (typeof object.reqMs === "object")
message.reqMs = new $util.LongBits(object.reqMs.low >>> 0, object.reqMs.high >>> 0).toNumber();
if (object.body != null)
if (typeof object.body === "string")
$util.base64.decode(object.body, message.body = $util.newBuffer($util.base64.length(object.body)), 0);
@ -271,6 +298,11 @@ export const api = $root.api = (() => {
object.op = 0;
object.seq = 0;
object.success = false;
if ($util.Long) {
let long = new $util.Long(0, 0, false);
object.reqMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.reqMs = options.longs === String ? "0" : 0;
if (options.bytes === String)
object.body = "";
else {
@ -287,6 +319,11 @@ export const api = $root.api = (() => {
object.seq = message.seq;
if (message.success != null && message.hasOwnProperty("success"))
object.success = message.success;
if (message.reqMs != null && message.hasOwnProperty("reqMs"))
if (typeof message.reqMs === "number")
object.reqMs = options.longs === String ? String(message.reqMs) : message.reqMs;
else
object.reqMs = options.longs === String ? $util.Long.prototype.toString.call(message.reqMs) : options.longs === Number ? new $util.LongBits(message.reqMs.low >>> 0, message.reqMs.high >>> 0).toNumber() : message.reqMs;
if (message.body != null && message.hasOwnProperty("body"))
object.body = options.bytes === String ? $util.base64.encode(message.body, 0, message.body.length) : options.bytes === Array ? Array.prototype.slice.call(message.body) : message.body;
return object;
@ -327,7 +364,7 @@ export const api = $root.api = (() => {
* Properties of a Ping.
* @memberof api
* @interface IPing
* @property {number|Long|null} [timeMs] Ping timeMs
* @property {number|Long|null} [ms] Ping ms
*/
/**
@ -346,12 +383,12 @@ export const api = $root.api = (() => {
}
/**
* Ping timeMs.
* @member {number|Long} timeMs
* Ping ms.
* @member {number|Long} ms
* @memberof api.Ping
* @instance
*/
Ping.prototype.timeMs = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
Ping.prototype.ms = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* Creates a new Ping instance using the specified properties.
@ -377,8 +414,8 @@ export const api = $root.api = (() => {
Ping.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.timeMs != null && Object.hasOwnProperty.call(message, "timeMs"))
writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.timeMs);
if (message.ms != null && Object.hasOwnProperty.call(message, "ms"))
writer.uint32(/* id 1, wireType 0 =*/8).int64(message.ms);
return writer;
};
@ -414,7 +451,7 @@ export const api = $root.api = (() => {
let tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
message.timeMs = reader.uint64();
message.ms = reader.int64();
break;
}
default:
@ -452,9 +489,9 @@ export const api = $root.api = (() => {
Ping.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.timeMs != null && message.hasOwnProperty("timeMs"))
if (!$util.isInteger(message.timeMs) && !(message.timeMs && $util.isInteger(message.timeMs.low) && $util.isInteger(message.timeMs.high)))
return "timeMs: integer|Long expected";
if (message.ms != null && message.hasOwnProperty("ms"))
if (!$util.isInteger(message.ms) && !(message.ms && $util.isInteger(message.ms.low) && $util.isInteger(message.ms.high)))
return "ms: integer|Long expected";
return null;
};
@ -470,15 +507,15 @@ export const api = $root.api = (() => {
if (object instanceof $root.api.Ping)
return object;
let message = new $root.api.Ping();
if (object.timeMs != null)
if (object.ms != null)
if ($util.Long)
(message.timeMs = $util.Long.fromValue(object.timeMs)).unsigned = true;
else if (typeof object.timeMs === "string")
message.timeMs = parseInt(object.timeMs, 10);
else if (typeof object.timeMs === "number")
message.timeMs = object.timeMs;
else if (typeof object.timeMs === "object")
message.timeMs = new $util.LongBits(object.timeMs.low >>> 0, object.timeMs.high >>> 0).toNumber(true);
(message.ms = $util.Long.fromValue(object.ms)).unsigned = false;
else if (typeof object.ms === "string")
message.ms = parseInt(object.ms, 10);
else if (typeof object.ms === "number")
message.ms = object.ms;
else if (typeof object.ms === "object")
message.ms = new $util.LongBits(object.ms.low >>> 0, object.ms.high >>> 0).toNumber();
return message;
};
@ -497,15 +534,15 @@ export const api = $root.api = (() => {
let object = {};
if (options.defaults)
if ($util.Long) {
let long = new $util.Long(0, 0, true);
object.timeMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
let long = new $util.Long(0, 0, false);
object.ms = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.timeMs = options.longs === String ? "0" : 0;
if (message.timeMs != null && message.hasOwnProperty("timeMs"))
if (typeof message.timeMs === "number")
object.timeMs = options.longs === String ? String(message.timeMs) : message.timeMs;
object.ms = options.longs === String ? "0" : 0;
if (message.ms != null && message.hasOwnProperty("ms"))
if (typeof message.ms === "number")
object.ms = options.longs === String ? String(message.ms) : message.ms;
else
object.timeMs = options.longs === String ? $util.Long.prototype.toString.call(message.timeMs) : options.longs === Number ? new $util.LongBits(message.timeMs.low >>> 0, message.timeMs.high >>> 0).toNumber(true) : message.timeMs;
object.ms = options.longs === String ? $util.Long.prototype.toString.call(message.ms) : options.longs === Number ? new $util.LongBits(message.ms.low >>> 0, message.ms.high >>> 0).toNumber() : message.ms;
return object;
};
@ -544,7 +581,7 @@ export const api = $root.api = (() => {
* Properties of a Pong.
* @memberof api
* @interface IPong
* @property {number|Long|null} [timeMs] Pong timeMs
* @property {number|Long|null} [pingMs] Pong pingMs
*/
/**
@ -563,12 +600,12 @@ export const api = $root.api = (() => {
}
/**
* Pong timeMs.
* @member {number|Long} timeMs
* Pong pingMs.
* @member {number|Long} pingMs
* @memberof api.Pong
* @instance
*/
Pong.prototype.timeMs = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
Pong.prototype.pingMs = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* Creates a new Pong instance using the specified properties.
@ -594,8 +631,8 @@ export const api = $root.api = (() => {
Pong.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.timeMs != null && Object.hasOwnProperty.call(message, "timeMs"))
writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.timeMs);
if (message.pingMs != null && Object.hasOwnProperty.call(message, "pingMs"))
writer.uint32(/* id 1, wireType 0 =*/8).int64(message.pingMs);
return writer;
};
@ -631,7 +668,7 @@ export const api = $root.api = (() => {
let tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
message.timeMs = reader.uint64();
message.pingMs = reader.int64();
break;
}
default:
@ -669,9 +706,9 @@ export const api = $root.api = (() => {
Pong.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.timeMs != null && message.hasOwnProperty("timeMs"))
if (!$util.isInteger(message.timeMs) && !(message.timeMs && $util.isInteger(message.timeMs.low) && $util.isInteger(message.timeMs.high)))
return "timeMs: integer|Long expected";
if (message.pingMs != null && message.hasOwnProperty("pingMs"))
if (!$util.isInteger(message.pingMs) && !(message.pingMs && $util.isInteger(message.pingMs.low) && $util.isInteger(message.pingMs.high)))
return "pingMs: integer|Long expected";
return null;
};
@ -687,15 +724,15 @@ export const api = $root.api = (() => {
if (object instanceof $root.api.Pong)
return object;
let message = new $root.api.Pong();
if (object.timeMs != null)
if (object.pingMs != null)
if ($util.Long)
(message.timeMs = $util.Long.fromValue(object.timeMs)).unsigned = true;
else if (typeof object.timeMs === "string")
message.timeMs = parseInt(object.timeMs, 10);
else if (typeof object.timeMs === "number")
message.timeMs = object.timeMs;
else if (typeof object.timeMs === "object")
message.timeMs = new $util.LongBits(object.timeMs.low >>> 0, object.timeMs.high >>> 0).toNumber(true);
(message.pingMs = $util.Long.fromValue(object.pingMs)).unsigned = false;
else if (typeof object.pingMs === "string")
message.pingMs = parseInt(object.pingMs, 10);
else if (typeof object.pingMs === "number")
message.pingMs = object.pingMs;
else if (typeof object.pingMs === "object")
message.pingMs = new $util.LongBits(object.pingMs.low >>> 0, object.pingMs.high >>> 0).toNumber();
return message;
};
@ -714,15 +751,15 @@ export const api = $root.api = (() => {
let object = {};
if (options.defaults)
if ($util.Long) {
let long = new $util.Long(0, 0, true);
object.timeMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
let long = new $util.Long(0, 0, false);
object.pingMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.timeMs = options.longs === String ? "0" : 0;
if (message.timeMs != null && message.hasOwnProperty("timeMs"))
if (typeof message.timeMs === "number")
object.timeMs = options.longs === String ? String(message.timeMs) : message.timeMs;
object.pingMs = options.longs === String ? "0" : 0;
if (message.pingMs != null && message.hasOwnProperty("pingMs"))
if (typeof message.pingMs === "number")
object.pingMs = options.longs === String ? String(message.pingMs) : message.pingMs;
else
object.timeMs = options.longs === String ? $util.Long.prototype.toString.call(message.timeMs) : options.longs === Number ? new $util.LongBits(message.timeMs.low >>> 0, message.timeMs.high >>> 0).toNumber(true) : message.timeMs;
object.pingMs = options.longs === String ? $util.Long.prototype.toString.call(message.pingMs) : options.longs === Number ? new $util.LongBits(message.pingMs.low >>> 0, message.pingMs.high >>> 0).toNumber() : message.pingMs;
return object;
};
@ -5265,7 +5302,6 @@ export const api = $root.api = (() => {
* @property {string|null} [avatar] TablePlayer avatar
* @property {number|null} [chip] TablePlayer chip
* @property {number|null} [status] TablePlayer status
* @property {number|null} [lastStatus] TablePlayer lastStatus
* @property {boolean|null} [master] TablePlayer master
* @property {number|null} [roundBetTimes] TablePlayer roundBetTimes
* @property {number|null} [totalBetChip] TablePlayer totalBetChip
@ -5338,14 +5374,6 @@ export const api = $root.api = (() => {
*/
TablePlayer.prototype.status = 0;
/**
* TablePlayer lastStatus.
* @member {number} lastStatus
* @memberof api.TablePlayer
* @instance
*/
TablePlayer.prototype.lastStatus = 0;
/**
* TablePlayer master.
* @member {boolean} master
@ -5430,8 +5458,6 @@ export const api = $root.api = (() => {
writer.uint32(/* id 5, wireType 0 =*/40).int32(message.chip);
if (message.status != null && Object.hasOwnProperty.call(message, "status"))
writer.uint32(/* id 6, wireType 0 =*/48).int32(message.status);
if (message.lastStatus != null && Object.hasOwnProperty.call(message, "lastStatus"))
writer.uint32(/* id 7, wireType 0 =*/56).int32(message.lastStatus);
if (message.master != null && Object.hasOwnProperty.call(message, "master"))
writer.uint32(/* id 8, wireType 0 =*/64).bool(message.master);
if (message.roundBetTimes != null && Object.hasOwnProperty.call(message, "roundBetTimes"))
@ -5503,10 +5529,6 @@ export const api = $root.api = (() => {
message.status = reader.int32();
break;
}
case 7: {
message.lastStatus = reader.int32();
break;
}
case 8: {
message.master = reader.bool();
break;
@ -5586,9 +5608,6 @@ export const api = $root.api = (() => {
if (message.status != null && message.hasOwnProperty("status"))
if (!$util.isInteger(message.status))
return "status: integer expected";
if (message.lastStatus != null && message.hasOwnProperty("lastStatus"))
if (!$util.isInteger(message.lastStatus))
return "lastStatus: integer expected";
if (message.master != null && message.hasOwnProperty("master"))
if (typeof message.master !== "boolean")
return "master: boolean expected";
@ -5651,8 +5670,6 @@ export const api = $root.api = (() => {
message.chip = object.chip | 0;
if (object.status != null)
message.status = object.status | 0;
if (object.lastStatus != null)
message.lastStatus = object.lastStatus | 0;
if (object.master != null)
message.master = Boolean(object.master);
if (object.roundBetTimes != null)
@ -5708,7 +5725,6 @@ export const api = $root.api = (() => {
object.avatar = "";
object.chip = 0;
object.status = 0;
object.lastStatus = 0;
object.master = false;
object.roundBetTimes = 0;
object.handType = null;
@ -5730,8 +5746,6 @@ export const api = $root.api = (() => {
object.chip = message.chip;
if (message.status != null && message.hasOwnProperty("status"))
object.status = message.status;
if (message.lastStatus != null && message.hasOwnProperty("lastStatus"))
object.lastStatus = message.lastStatus;
if (message.master != null && message.hasOwnProperty("master"))
object.master = message.master;
if (message.roundBetTimes != null && message.hasOwnProperty("roundBetTimes"))
@ -7078,6 +7092,7 @@ export const api = $root.api = (() => {
* @interface IReqBetting
* @property {number|null} [betType] ReqBetting betType
* @property {number|null} [betChip] ReqBetting betChip
* @property {number|null} [operator] ReqBetting operator
*/
/**
@ -7111,6 +7126,14 @@ export const api = $root.api = (() => {
*/
ReqBetting.prototype.betChip = 0;
/**
* ReqBetting operator.
* @member {number} operator
* @memberof api.ReqBetting
* @instance
*/
ReqBetting.prototype.operator = 0;
/**
* Creates a new ReqBetting instance using the specified properties.
* @function create
@ -7139,6 +7162,8 @@ export const api = $root.api = (() => {
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.betType);
if (message.betChip != null && Object.hasOwnProperty.call(message, "betChip"))
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.betChip);
if (message.operator != null && Object.hasOwnProperty.call(message, "operator"))
writer.uint32(/* id 3, wireType 0 =*/24).int32(message.operator);
return writer;
};
@ -7181,6 +7206,10 @@ export const api = $root.api = (() => {
message.betChip = reader.int32();
break;
}
case 3: {
message.operator = reader.int32();
break;
}
default:
reader.skipType(tag & 7);
break;
@ -7222,6 +7251,9 @@ export const api = $root.api = (() => {
if (message.betChip != null && message.hasOwnProperty("betChip"))
if (!$util.isInteger(message.betChip))
return "betChip: integer expected";
if (message.operator != null && message.hasOwnProperty("operator"))
if (!$util.isInteger(message.operator))
return "operator: integer expected";
return null;
};
@ -7241,6 +7273,8 @@ export const api = $root.api = (() => {
message.betType = object.betType | 0;
if (object.betChip != null)
message.betChip = object.betChip | 0;
if (object.operator != null)
message.operator = object.operator | 0;
return message;
};
@ -7260,11 +7294,14 @@ export const api = $root.api = (() => {
if (options.defaults) {
object.betType = 0;
object.betChip = 0;
object.operator = 0;
}
if (message.betType != null && message.hasOwnProperty("betType"))
object.betType = message.betType;
if (message.betChip != null && message.hasOwnProperty("betChip"))
object.betChip = message.betChip;
if (message.operator != null && message.hasOwnProperty("operator"))
object.operator = message.operator;
return object;
};

135
src/api/websocket.js

@ -5,6 +5,7 @@ import { fetchOpMap, fetchRouteWs } from '@/api/api'
import { getStorage, removeStorage } from '@/utils/storage';
import { redirectTo, showToast } from '@/utils/application';
import { setUserInfo } from '@/store/user'
import { connecting, connected, disconnect, setTTL } from '@/store/conn'
import { isIn } from '@/utils/collect';
const { api } = proto
@ -24,11 +25,15 @@ const websocket = {
msgListener: {}, // {op: func}
waitInitCalls: [],
reconnectInterval: -1,
init(token, { offset, opFail, opSuccess, opPathMap, nameOpMap }, { wsAddr }, callback) { // callback 连接失败不一定调用
this.status = 4;
callback = callback || (() => {});
// 连接状态判定
this.token = token;
closeConn() {
if (this.conn) {
const conn = this.conn;
this.conn = null;
conn.close();
}
},
init: async function({ offset, opFail, opSuccess, opPathMap, nameOpMap }, { wsAddr }) { // callback 连接失败不一定调用
// this.status = 0;
this.offset = offset || 0;
this.opFail = opFail;
this.opSuccess = opSuccess;
@ -36,85 +41,105 @@ const websocket = {
this.nameOpMap = nameOpMap || {};
this.wsAddr = wsAddr;
// window.proto = proto;
const ws = new WebSocket(`ws://${wsAddr}/api/conn/ws`)
if (this.conn) {
this.conn.close();
return await this.connect();
},
connect: function() {
return new Promise((resolve, reject) => {
const token = getStorage('_t');
if (!token) {
return reject('storage token not exists!');
}
this.conn = ws
ws.binaryType = 'arraybuffer'
ws.onopen = (e) => {
// 关闭定时重连
clearInterval(this.reconnectInterval);
this.reconnectInterval = -1;
store.dispatch(connecting());
this.closeConn(); // 关闭之前连接
const ws = new WebSocket(`ws://${this.wsAddr}/api/conn/ws`);
this.conn = ws;
ws.binaryType = 'arraybuffer';
ws.onopen = e => {
// 关闭当前定时重连 TODO handle
// clearInterval(this.reconnectInterval);
// this.reconnectInterval = -1;
this.status = 1;
// 连接后立即认证连接
const req = api.ReqIdentity.create({ token });
// const reqBuffer = api.ReqIdentity.encode(req).finish()
this.send(req, res => {
this.status = 2;
// const dispatch = useDispatch();
// window.res = res;
// console.log(store, setUserInfo(res))
store.dispatch(connected());
store.dispatch(setUserInfo(res.toJSON()));
console.log('identity success:', res)
// console.log('identity success:', res)
try { callback(null) } catch(e) { console.error('error:', e); }
// 依次发送等待连接的消息队列
for (let i = 0; i < this.waitInitCalls.length; i++) {
if (this.waitInitCalls[i]) {
try {
this.waitInitCalls[i]();
this.waitInitCalls[i] = null;
}catch(e) {
showToast({title: e});
console.log('execut wait handler error:', e);
}
}
}
resolve(res);
}, err => {
removeStorage('_t')
showToast({title: err})
console.error('连接认证失败:', err)
this.closeConn();
store.dispatch(disconnect());
removeStorage('_t');
showToast({title: err});
console.error('连接认证失败:', err);
reject('连接认证失败:' + err);
try { callback(err) } catch(e) { console.error('error:', e); }
// try { callback(err) } catch(e) { console.error('ws identity callback error: ', e); }
})
}
ws.onerror = (a, b, c) => {
ws.onerror = e => {
this.closeConn();
this.status = 3;
console.log('ws error:', a, b, c)
// this.reconnectInterval = setInterval(() => {
// this.reconnect();
// }, Math.random() * 3 + 3);
store.dispatch(disconnect());
console.log('ws connect failed.');
reject('ws connect failed!');
}
ws.onclose = e => {
this.status = 3;
console.log('ws close', e)
if (this.reconnectInterval < 0) {
this.reconnectInterval = setInterval(() => {
this.reconnect();
}, Math.random() * 3 + 4);
store.dispatch(disconnect());
console.log('ws connection close.')
if (this.conn === ws) {
this.reconnectPolicy();
// this.reconnectInterval = setInterval(() => {
// }, Math.random() * 3 + 4);
}
}
ws.onmessage = (e) => {
// console.log('msg:', e.data)
const wrap = api.ProtoWrap.decode(new Uint8Array(e.data))
// 解码响应体
const opPath = this.opPathMap[wrap.op]
if (!opPath) {
console.error('res op not exists!', wrap.op)
console.error('unknow res op:', wrap.op)
return
}
const res = proto[opPath[0]][opPath[1]].decode(wrap.body)
// const res = api.ResIdentity.decode(wrap.body)
console.log('res msg:', res)
if (wrap.reqMs > 0) {
const ttl = Date.now() - wrap.reqMs;
store.dispatch(setTTL(ttl));
// console.log('ping:', ttl + "ms")
}
if (wrap.seq !== 0) {
// 对应请求callback
const caller = this.waitCall[wrap.seq];
delete this.waitCall[wrap.seq];
// console.log(waitCall, this.waitCall);
if (caller) {
if (wrap.op === opFail) {
if (wrap.op === this.opFail) {
if (res.code === 401) { // 重新登录
setTimeout(() => redirectTo({url: '/pages/login/login'}), 500);
}
@ -125,14 +150,16 @@ const websocket = {
return;
}
}
// 找消息类型的listen执行
const listener = this.msgListener[wrap.op];
if (listener) {
listener(res);
return;
}
// 错误消息,提示一下
if (wrap.op === opFail) {
if (wrap.op === this.opFail) {
console.error('ResFail:', res)
showToast({title: res.code + ":" + res.msg})
if (isIn(res.code, 401, 403)) { // 认证失败,异地登录
@ -141,19 +168,35 @@ const websocket = {
return;
}
console.log('no handler msg:', wrap.op, res)
// 未找到消息对应handler
console.log('not found msg handler:', wrap.op, res)
}
});
},
// 重新连接,
reconnect() {
if (this.status === 4) {
reconnectPolicy() {
if (this.reconnectInterval < 0 && this.status === 4) {
return;
}
this.reconnectInterval = setInterval(async () => {
console.log('ws reconnecting...');
// TODO store 状态
this.init(this.token, this, this, err => {
console.log('reconnect end:', err)
});
const token = getStorage('_t');
if (!token) {
clearInterval(this.reconnectInterval);
this.reconnectInterval = -1;
// 无token跳转到login
setTimeout(() => redirectTo({url: '/pages/login/login'}), 500);
return;
}
try {
const res = await this.connect();
console.log('reconnect success:', res);
clearInterval(this.reconnectInterval);
this.reconnectInterval = -1;
}catch(err) {
console.log('reconnect error:', err);
}
}, 3000);
},
waitCall: {}, // 等待响应的 callback 列表
send(msg, resCall, errCall) {
@ -170,7 +213,7 @@ const websocket = {
const op = this.nameOpMap[typeUrl];
console.log('req', typeUrl, op);
const msgBufer = msg.constructor.encode(msg).finish();
const wrap = api.ProtoWrap.create({ ver: 1, op: op, seq: this.seq++, body: msgBufer });
const wrap = api.ProtoWrap.create({ ver: 1, op: op, seq: this.seq++, reqMs: Date.now(), body: msgBufer });
const wrapBuffer = api.ProtoWrap.encode(wrap).finish();
this.conn.send(wrapBuffer);
if (resCall) {

3
src/pages/login/login.jsx

@ -38,7 +38,8 @@ function Login() {
setStorage('_t', tokenRes.data.token);
const wsRes = await fetchRouteWs();
// websocket
ws.init(tokenRes.data.token, opMapRes.data, wsRes.data);
const res = await ws.init(opMapRes.data, wsRes.data);
console.log('ws login success:', res)
showToast({title: tokenRes.msg || '登录成功', duration: 800});
//
setTimeout(() => redirectTo({url: '/pages/lobby/lobby'}), 800);

13
src/store/conn.js

@ -3,22 +3,25 @@ import { createSlice } from '@reduxjs/toolkit';
const connSlice = createSlice({
name: 'conn',
initialState: {
status: 0, // 连接状态,0未连接,1,已连接,2已关闭
status: 1, // 连接状态: 1已断开,2连接中,3已连接
ttl: 0, // 延迟ms
},
reducers: {
connecting: state => {
state.status = 2
},
connected: state => {
state.status = 1;
state.status = 3;
},
disconnect: state => {
state.status = 2;
state.status = 4;
},
setTTL: (state, action) => {
state.ttl = action.playload;
state.ttl = action.payload;
}
}
})
export default connSlice
export const { connected, disconnect, setTTL } = connSlice.actions
export const { connecting, connected, disconnect, setTTL } = connSlice.actions

Loading…
Cancel
Save