fix: CTP连接改后台异步,避免多路重连互相阻塞
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+93
-40
@@ -69,18 +69,95 @@
|
||||
if (marketHint) marketHint.hidden = priceType !== 'market';
|
||||
}
|
||||
|
||||
function updateCtpBadge(connected) {
|
||||
function updateCtpBadge(connected, connecting) {
|
||||
var ctpBadge = document.getElementById('ctp-badge');
|
||||
var btnConnect = document.getElementById('btn-ctp-connect');
|
||||
if (ctpBadge) {
|
||||
ctpBadge.textContent = connected ? 'CTP 已连接' : 'CTP 未连接';
|
||||
ctpBadge.className = 'badge ' + (connected ? 'profit' : 'planned');
|
||||
if (connecting) {
|
||||
ctpBadge.textContent = 'CTP 连接中';
|
||||
ctpBadge.className = 'badge planned';
|
||||
} else {
|
||||
ctpBadge.textContent = connected ? 'CTP 已连接' : 'CTP 未连接';
|
||||
ctpBadge.className = 'badge ' + (connected ? 'profit' : 'planned');
|
||||
}
|
||||
}
|
||||
if (btnConnect && connected) {
|
||||
btnConnect.textContent = '重连 CTP';
|
||||
if (btnConnect) {
|
||||
if (connecting) {
|
||||
btnConnect.textContent = '连接中…';
|
||||
btnConnect.disabled = true;
|
||||
} else {
|
||||
btnConnect.disabled = false;
|
||||
btnConnect.textContent = connected ? '重连 CTP' : '连接 CTP';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function waitForCtpConnected(maxMs) {
|
||||
var deadline = Date.now() + (maxMs || 35000);
|
||||
function tick() {
|
||||
return fetch('/api/ctp/status')
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
var st = d.status || {};
|
||||
if (st.connected) {
|
||||
updateCtpBadge(true, false);
|
||||
if (d.account && d.account.available != null) {
|
||||
var avail = document.getElementById('avail-display');
|
||||
if (avail) avail.textContent = Number(d.account.available).toFixed(2);
|
||||
}
|
||||
pollPositions();
|
||||
return true;
|
||||
}
|
||||
if (st.connecting && Date.now() < deadline) {
|
||||
updateCtpBadge(false, true);
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(function () { resolve(tick()); }, 2000);
|
||||
});
|
||||
}
|
||||
updateCtpBadge(false, false);
|
||||
if (st.last_error) {
|
||||
var hint = document.querySelector('.ctp-install-hint');
|
||||
if (hint) hint.textContent = st.last_error;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.catch(function () { updateCtpBadge(false, false); return false; });
|
||||
}
|
||||
return tick();
|
||||
}
|
||||
|
||||
function requestCtpConnect(force) {
|
||||
updateCtpBadge(false, true);
|
||||
return fetch('/api/ctp/connect', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ force: !!force, auto: !force })
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
if (d.status && d.status.connected) {
|
||||
updateCtpBadge(true, false);
|
||||
pollPositions();
|
||||
return d;
|
||||
}
|
||||
if (d.connecting || (d.status && d.status.connecting)) {
|
||||
return waitForCtpConnected(35000).then(function (ok) {
|
||||
if (!ok && d.error) alert(d.error);
|
||||
else if (!ok && d.status && d.status.last_error) alert(d.status.last_error);
|
||||
return d;
|
||||
});
|
||||
}
|
||||
if (!d.ok) {
|
||||
updateCtpBadge(false, false);
|
||||
alert(d.error || (d.status && d.status.last_error) || '连接失败');
|
||||
}
|
||||
return d;
|
||||
})
|
||||
.catch(function () {
|
||||
updateCtpBadge(false, false);
|
||||
});
|
||||
}
|
||||
|
||||
function refreshQuote() {
|
||||
var sym = selectedSymbol();
|
||||
var lots = isRiskMode() ? (effectiveLots() || 1) : (lotsInput ? lotsInput.value : '1');
|
||||
@@ -155,29 +232,12 @@
|
||||
function tryAutoCtpReconnect() {
|
||||
if (ctpReconnecting) return;
|
||||
var now = Date.now();
|
||||
if (now - lastCtpReconnectAt < 30000) return;
|
||||
if (now - lastCtpReconnectAt < 60000) return;
|
||||
lastCtpReconnectAt = now;
|
||||
ctpReconnecting = true;
|
||||
fetch('/api/ctp/connect', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ auto: true })
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
if (d.ok && d.status && d.status.connected) {
|
||||
updateCtpBadge(true);
|
||||
var avail = document.getElementById('avail-display');
|
||||
if (avail && d.account && d.account.available != null) {
|
||||
avail.textContent = Number(d.account.available).toFixed(2);
|
||||
}
|
||||
pollPositions();
|
||||
}
|
||||
})
|
||||
.catch(function () { /* ignore */ })
|
||||
.finally(function () {
|
||||
ctpReconnecting = false;
|
||||
});
|
||||
requestCtpConnect(false).finally(function () {
|
||||
ctpReconnecting = false;
|
||||
});
|
||||
}
|
||||
|
||||
function showOrderMsg(text, ok) {
|
||||
@@ -342,9 +402,14 @@
|
||||
var cap = document.getElementById('cap-display');
|
||||
if (cap && data.capital != null) cap.textContent = Number(data.capital).toFixed(2);
|
||||
var connected = data.ctp_status && data.ctp_status.connected;
|
||||
updateCtpBadge(!!connected);
|
||||
var connecting = data.ctp_status && data.ctp_status.connecting;
|
||||
updateCtpBadge(!!connected, !!connecting);
|
||||
var rows = data.rows || [];
|
||||
if (!connected) {
|
||||
if (connecting) {
|
||||
list.innerHTML = '<div class="empty-hint">CTP 连接中,请稍候…</div>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = '<div class="empty-hint">CTP 未连接,正在尝试自动重连…</div>';
|
||||
tryAutoCtpReconnect();
|
||||
return;
|
||||
@@ -446,19 +511,7 @@
|
||||
var btnConnect = document.getElementById('btn-ctp-connect');
|
||||
if (btnConnect) {
|
||||
btnConnect.addEventListener('click', function () {
|
||||
btnConnect.disabled = true;
|
||||
btnConnect.textContent = '连接中…';
|
||||
fetch('/api/ctp/connect', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
if (!d.ok) { alert(d.error || '连接失败'); return; }
|
||||
updateCtpBadge(true);
|
||||
pollPositions();
|
||||
})
|
||||
.finally(function () {
|
||||
btnConnect.disabled = false;
|
||||
btnConnect.textContent = '重连 CTP';
|
||||
});
|
||||
requestCtpConnect(true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user