一、总体流程
- 数据首先通过receiver接受层接收,去掉标识头和标识尾;
- 再进入depacker解包层进行解包,把标识头分解出来并解析;
- 之后发给handler处理层根据不同的消息id选择使用不同的业务逻辑;
- 如果有应答,则通过sender发送层发送到socket上
二、业务流程及问题
1.链路登录流程
注意点:
- 上级平台和下级平台各有一个服务器,且要连接一个对方的服务器,这样就能构成两条链路。
- 登录的消息体需要给用户名,密码,端口号和ip,如果是2019版的还需要接入码。
- 登陆应答以及从链路连接请求需要给一个校验码,这里的校验码不是循环冗余校验码的那个校验码,是随机一个数,下级平台保证收到的两个校验码一致才会应答从链路连接。
nodejs代码遇到的问题及解决方式:
Q1:作为下级平台需要一直发送登录请求,直到连接上主链路服务器为止。但是一旦连接不上就会报错终止程序。
解决办法:
法一:
socket.on('error',()=>{在这里面进行重连,就不会报错出去})
法二:
process.on('uncaughtException',()=>{在这里面进行重连})
// uncaughtException,报错进这里就不会中断程序
Q2:作为上级平台需要进行安全验证
解决办法:
仔细看协议,安全验证主要就是用户名,密码,ip和端口号还有接入码的验证
2.业务处理
Q1:到底是gbk还是utf8
解决办法:
有的地方上写着用gbk有的地方没写,没写的时候就要注意这个字段是否有中文存在的可能,比如车牌号肯定有中文,只要有中文一律使用gbk编码,在协议的数据类型介绍里面有详细描述(但我第一次看的时候完全忽视)
3.多个下级/上级的情况处理
Q1:如果有多个平台与本平台进行连接,我们需要很多个服务,但手动起并不现实
解决办法:
通过一个mian文件创建多个子进程,子进程的配置信息放在一个config.js的文件里,从数据库调用查找(里面有密钥,接入码,密码,用户名等)
const { fork } = require('child_process');
const {logger} = require('./utils/logger')
let cg = require('./config')
const runningProcesses = []
function startProcess(temp){ // 启动子进程
if(temp.amSuperiorPlatform===1){
const childProcess = fork('上级文件路径', [temp.id, temp.treatyType, temp.mainLinkPort])
childProcess.on('close',(code)=>{
logger.info(temp.forwardingName+'子进程已关闭,code为:'+code)
const index = runningProcesses.indexOf(childProcess);
if(index!==-1){
runningProcesses.splice(index,1)
}
})
runningProcesses.push(childProcess);
}else{
const childProcess = fork('下级文件路径', [temp.id, temp.treatyType, temp.mainLinkPort, temp.subordinateLinkPort])
childProcess.on('close',(code)=>{
logger.info(temp.forwardingName+'子进程已关闭,code为:'+code)
const index = runningProcesses.indexOf(childProcess);
if(index!==-1){
runningProcesses.splice(index,1)
}
})
runningProcesses.push(childProcess);
}
}
function stopProcess(index) { // 关闭子程序
if (runningProcesses[index]) {
console.log(`停止子进程 `);
runningProcesses[index].kill();
}
}
function updateProcesses(processes){
processes.forEach((temp,index)=>{
if (temp.enable) {
if (!runningProcesses[index]) {
console.log(`启动子进程 `);
startProcess(temp);
}
} else {
stopProcess(index);
}
})
}
async function main(){
let temp = await cg.getConfig(-1)
// 启动定时器,每隔一段时间更新子进程状态
const updateInterval = 5000; // 5秒
setInterval(()=>{updateProcesses(temp)}, updateInterval);
}
main()
Q2:当启用多个进程的时候可能会调用同一个js组件文件,如果每个进程都要对此文件的变量进行修改,会不会影响并行的进程?
答案:不会,不同进程互不干扰,地址不同