一個基於套接字實現長鏈接的小型expressexpress
邏輯: 首先把routerUrl目錄下的函數初始化緩存起來,經過Router.request調用緩存起來的
函數,這個函數其實是register.set方法,主要是開始運行函數鏈,經過
register.next 運行下一個函數。緩存
函數流 main.js --> Router.request --> register.set --> register.next --> sock.writeapp
main.jssocket
'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文件async
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文件ui
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;
註冊文件this
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的思想,要用在實際開發中還須要斷線重連,優化鏈接,異常處理等功能。url