详解一个基于套接字实现长连接的express
逻辑:首先把routerUrl目录下的函数初始化缓存起来,通过Router.request调用缓存起来的函数,这个函数实际上是register.set方法,主要是开始运行函数链,通过register.next运行下一个函数。
函数流main.js-->Router.request-->register.set-->register.next-->sock.write
main.js
'usestrict';
constrouterUrl='router';//当前目录下的router地址
constRouter=require('./net/Router');//初始化路由
constnet=require('net');
constport='3000';
Router.init(routerUrl);
constapp=sock=>{
sock.on('data',function(data){
try{
Router.request(data,sock);
}catch(error){
console.log(error)
}
});
sock.on('error',(err)=>{
console.log(err)
})
//为这个socket实例添加一个"close"事件处理函数
sock.on('close',function(data){
console.log('clone')
})
}
constserver=net.createServer(app);
server.listen(port,()=>{
console.log(`Startuinenv${process.env.NODE_ENV||'development'}onport${port}`);
});
server.on('error',(err)=>{
console.log(err)
})
路由加载:
Router.js文件
constfs=require('fs');
const_=require('lodash');
varpath=require("path");
varROOT_PATH=path.resolve(__dirname);
classRouter{
constructor(){
this.routeMap={};
}
/**
*通过routerUrl来匹配目录下的文件,加载进来
*@param{*}routerUrl
*/
init(routerUrl){
letfiles=fs.readdirSync(path.join(ROOT_PATH,`../${routerUrl}`));
return_.reduce(files,(config,file)=>{
letsvc=require(path.join(ROOT_PATH,`../${routerUrl}/${file}`));
this.routeMap={
[file.split('.')[0]]:svc.get()
};
},{})
}
/**
*通过url匹配加载的router,其他字段可自定义,url这里的逻辑也可改成配置文件进行配置,类似于protobuf
*@param{*}data{url,body}
*@param{*}sock
*/
request(data,sock){
try{
this.routeMap[result.url.split('/')[1]][result.url.replace(`/${result.url.split('/')[1]}`,'')](data,sock);
}catch(error){
sock.write(error);
}
}
}
module.exports=newRouter();
中间件:
register.js文件
constNext=require('./next');
classRegister{
constructor(){
this._init={};
}
set(url,...handlers){
this._init[url]=async(data,sock)=>{
try{
letnext=newNext(handlers);
next.run(data,sock);
}catch(error){
sock.write(error);
}
};
}
get(){
returnthis._init;
}
}
module.exports=newRegister();
nest.js文件
classNext{
constructor(stack){
this.index=0;
this.stack=stack;
this.data=null;
this.sock=null;
}
run(data,sock){
this.data=data;
this.sock=sock;
this.stack[this.index](data,sock,this.next.bind(this));
}
next(){
if(arguments[0]&&arguments[0]===+arguments[0]&&+arguments[0]
注册文件
constinit=require('../net/register');
init.set('/test',
(data,sock,next)=>{
next()
},
async(data,sock)=>{
try{
sock.write(test);
}catch(e){
sock.write(e);
}
});
总结:这个项目只是用来歇息express的思想,要用在实际开发中还需要断线重连,优化连接,异常处理等功能。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。