JavaScript

超轻量级php框架startmvc

详解一个基于套接字实现长连接的express

更新时间:2020-08-19 05:12:01 作者:startmvc
逻辑:首先把routerUrl目录下的函数初始化缓存起来,通过Router.request调用缓存起来的函数,这

逻辑: 首先把routerUrl目录下的函数初始化缓存起来,通过Router.request调用缓存起来的函数,这个函数实际上是register.set方法,主要是开始运行函数链,通过register.next 运行下一个函数。

函数流 main.js --> Router.request --> register.set --> register.next --> sock.write

main.js


'use strict';
const routerUrl = 'router'; // 当前目录下的router地址
const Router = require('./net/Router'); // 初始化路由
const net = require('net');
const port = '3000';
Router.init(routerUrl);
const app = 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')
 })
}
const server = net.createServer(app);

server.listen(port, () => {
 console.log(`Startu in env ${process.env.NODE_ENV || 'development'} on port ${port}`);
});

server.on('error', (err) => {
 console.log(err)
})

路由加载:

Router.js文件


const fs = require('fs');
const _ = require('lodash');
var path = require("path");
var ROOT_PATH = path.resolve(__dirname);
class Router {
 constructor() {
 this.routeMap = {};
 }
 /**
 * 通过routerUrl来匹配目录下的文件,加载进来
 * @param {*} routerUrl
 */
 init(routerUrl) {
 let files = fs.readdirSync(path.join(ROOT_PATH, `../${routerUrl}`));
 return _.reduce(files, (config, file) => {
 let svc = 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 = new Router();

中间件:

register.js文件


const Next = require('./next');

class Register {
 constructor() {
 this._init = {};
 }
 <!-- 初始化router函数,开始运行函数链 -->
 set(url, ...handlers) {

 this._init[url] = async (data, sock) => {
 try {
 let next = new Next(handlers);
 next.run(data, sock); 
 } catch (error) {
 sock.write(error);
 }
 };
 }
 <!-- 获取初始化的router函数 -->
 get() {
 return this._init;
 }
}

module.exports = new Register();

nest.js文件


class Next {
 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));
 }
 <!-- 调到下一个中间件,若带参数就跳到第arguments[0]步 -->
 next() {
 if (arguments[0] && arguments[0] === +arguments[0] && +arguments[0] < this.stack.length) {
 this.index = +arguments[0];
 return this.run(data, this.sock);
 }
 this.index++;
 this.run(this.data, this.sock);
 }
}

module.exports = Next;

注册文件


const init = require('../net/register');

init.set('/test',
 (data, sock, next) => {
 next()
 },
 async (data, sock) => {
 try {
 sock.write(test);
 } catch (e) {
 sock.write(e);
 }
 });

总结:这个项目只是用来歇息express的思想,要用在实际开发中还需要断线重连,优化连接,异常处理等功能。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

express套接字实现长连接 express 长连接