詳解一個(gè)基于套接字實(shí)現(xiàn)長連接的express
邏輯: 首先把routerUrl目錄下的函數(shù)初始化緩存起來,通過Router.request調(diào)用緩存起來的函數(shù),這個(gè)函數(shù)實(shí)際上是register.set方法,主要是開始運(yùn)行函數(shù)鏈,通過register.next 運(yùn)行下一個(gè)函數(shù)。
函數(shù)流 main.js --> Router.request --> register.set --> register.next --> sock.write
main.js
'use strict'; const routerUrl = 'router'; // 當(dāng)前目錄下的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) }) // 為這個(gè)socket實(shí)例添加一個(gè)"close"事件處理函數(shù) 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來匹配目錄下的文件,加載進(jìn)來 * @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這里的邏輯也可改成配置文件進(jìn)行配置,類似于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函數(shù),開始運(yùn)行函數(shù)鏈 --> 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函數(shù) --> 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; } <!-- 運(yùn)行中間件 --> run(data, sock) { this.data = data; this.sock = sock; this.stack[this.index](data, sock, this.next.bind(this)); } <!-- 調(diào)到下一個(gè)中間件,若帶參數(shù)就跳到第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); } });
總結(jié):這個(gè)項(xiàng)目只是用來歇息express的思想,要用在實(shí)際開發(fā)中還需要斷線重連,優(yōu)化連接,異常處理等功能。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
node+koa+canvas繪制出貨單、收據(jù)票據(jù)的方法
在生成票據(jù)需求中,我們會(huì)想到前端生成或者后端生成返回圖片地址訪問兩個(gè)方法,前端生成則不需要調(diào)用接口,而后端是在完成整個(gè)流程時(shí)就進(jìn)行生成然后把上傳的地址保存數(shù)據(jù)庫,這篇文章主要介紹了node+koa+canvas繪制出貨單,收據(jù),票據(jù),需要的朋友可以參考下2022-09-09npm?install?-g?@vue/cli常見問題解決匯總
這篇文章主要給大家介紹了關(guān)于npm?install?-g?@vue/cli常見問題解決的相關(guān)資料,文中通過實(shí)例代碼將解決的方式介紹的非常詳細(xì),對遇到這個(gè)問題的朋友具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-08-08nodejs實(shí)現(xiàn)郵件發(fā)送服務(wù)實(shí)例分享
本文給大家講解的是簡單的使用nodejs搭建郵件發(fā)送服務(wù)的一個(gè)實(shí)例,非常的好用,有需要的小伙伴可以參考下2017-03-03node.js調(diào)用Chrome瀏覽器打開鏈接地址的方法
其實(shí)在Node.JS中打開瀏覽器網(wǎng)址非常簡單,但還是有必要整理下分享給有需要的朋友們,這篇文章主要給大家介紹了node.js如何調(diào)用Chrome瀏覽器打開鏈接地址的方法,文中介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起看看吧。2017-05-05使用nodejs開發(fā)cli項(xiàng)目實(shí)例
這篇文章主要介紹了使用nodejs開發(fā)cli項(xiàng)目實(shí)例,本文講解使用generator-cli-starter實(shí)現(xiàn)cli項(xiàng)目的開發(fā),需要的朋友可以參考下2015-06-06PHPStorm中如何對nodejs項(xiàng)目進(jìn)行單元測試詳解
這篇文章主要給大家介紹了關(guān)于PHPStorm中如何對nodejs項(xiàng)目進(jìn)行單元測試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02