客户端的动态线路选择问题
大概要实现的逻辑如下:
- 读配置文件,得到服务器列表。
- 向列表中的服务器均发送请求。
- 在获得第一个请求响应后,终端其它连接,当前响应主机IP即为选出的主机IP。
- 在程序运行过程中,如果当选主机连接不可以,重复选举过程,重新选举主机。
- 如果所有主机都不可用,程序退出。
主请求体如下:
let superRequest = (hostname, path, onResponse, onError, ext_data) => {
let superOption = {
hostname: hostname,
port: '443',
path: path,
method: 'GET',
rejectUnauthorized: false,
requestCert: true,
headers: {
'Accept-Encoding': 'gzip, deflate'
}
};
const req = https.request(superOption, (res) => {
});
req.write('');
if (ext_data.req_type === REQFORJSON) {
global_params.connect_server_request_array.push(req);
}
req.on('response', (response) => (onResponse(response, req, ext_data))).on('error', (e) => (onError(e, req, ext_data))).end();
};
主请求体的回调函数如下:
let onChcpJsonResponse = (response, req, ext_data) => {
while (global_params.connect_server_request_array.length > 0) {
let local_req = global_params.connect_server_request_array.pop();
if (local_req !== req) {
local_req.abort();
}
}
if (global_params.connect_server_return_flag) {
global_params.connect_server_return_flag = false;
global_params.final_elected_url = ext_data.server_url;
console.log('Elected url:' + global_params.final_elected_url);
let body = '';
if (response.headers['content-encoding'] === undefined) {
response.on('data', data => {
body += data;
});
response.on('end', () => {
onChcpJsonResponseOnEnd(req, body)
});
response.on('error', e => {
console.log('error' + e.toString());
req.end();
});
} else {
switch (response.headers['content-encoding']) {
case 'gzip':
let gunzip = zlib.createGunzip();
response.pipe(gunzip);
gunzip.on('data', data => {
body += data;
});
gunzip.on('end', () => {
onChcpJsonResponseOnEnd(req, body)
});
gunzip.on('error', e => {
console.log('error' + e.toString());
req.end();
});
break;
default:
req.end();
}
}
}
};
如果所有主机不可达,逻辑如下:
let onChcpJsonError = (e, req, ext_data) => {
if (ext_data.server_url === global_params.final_elected_url) {
global_params.final_elected_url = '';
getRemoteChcpJson();
} else {
console.error("Host: " + ext_data.server_url + " request aborted or unreachable!");
if (++global_params.connect_server_attempt_count >= update_files_content.local_json_content.server_urls.length) {
global_params.connect_server_attempt_count = 0;
global_params.final_elected_url = '';
const options = {
type: 'error',
title: '更新',
message: "与服务器连接丢失,程序即将关闭!",
buttons: ['确定'],
};
dialog.showMessageBox(options, () => app.quit());
}
}
};
网友评论