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


Posted in Javascript onMarch 28, 2019

逻辑: 首先把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的思想,要用在实际开发中还需要断线重连,优化连接,异常处理等功能。

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

Javascript 相关文章推荐
javascript+dom树型菜单类,希望朋友们一起进步
May 03 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
May 11 Javascript
node.js中的socket.io入门实例
Apr 26 Javascript
10个JavaScript中易犯小错误
Feb 14 Javascript
js实现精确到秒的日期选择器完整实例
Apr 30 Javascript
js仿京东轮播效果 选项卡套选项卡使用
Jan 12 Javascript
js仿淘宝评价评分功能
Feb 28 Javascript
js遍历获取表格内数据的方法(必看)
Apr 06 Javascript
EasyUI Tree树组件无限循环的解决方法
Sep 27 Javascript
利用VS Code开发你的第一个AngularJS 2应用程序
Dec 15 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
Jan 27 jQuery
vue v-for出来的列表,点击某个li使得当前被点击的li字体变红操作
Jul 17 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
Mar 28 #Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
Mar 28 #Javascript
深入理解es6块级作用域的使用
Mar 28 #Javascript
详解在网页上通过JS实现文本的语音朗读
Mar 28 #Javascript
详解React服务端渲染从入门到精通
Mar 28 #Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
Mar 28 #Javascript
JavaScript刷新页面的几种方法总结
Mar 28 #Javascript
You might like
PHP 编程的 5个良好习惯
2009/02/20 PHP
php面向对象全攻略 (十一)__toString()用法 克隆对象 __call处理调用错误
2009/09/30 PHP
总结的一些PHP开发中的tips(必看篇)
2017/03/24 PHP
javascript里的条件判断
2007/02/27 Javascript
dropdownlist之间的互相联动实现(显示与隐藏)
2009/11/24 Javascript
为原生js Array增加each方法
2012/04/07 Javascript
javascript弹出层输入框(示例代码)
2013/12/11 Javascript
JS 对象属性相关(检查属性、枚举属性等)
2015/04/05 Javascript
Nodejs Express4.x开发框架随手笔记
2015/11/23 NodeJs
JS监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
2016/08/05 Javascript
BootStrap与Select2使用小结
2017/02/17 Javascript
js+html制作简单日历的方法
2017/06/27 Javascript
Vue组件化开发之通用型弹出框的实现
2020/02/28 Javascript
Vue中正确使用Element-UI组件的方法实例
2020/10/13 Javascript
关于angular 8.1使用过程中的一些记录
2020/11/25 Javascript
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
python查看zip包中文件及大小的方法
2015/07/09 Python
Python运行报错UnicodeDecodeError的解决方法
2016/06/07 Python
Python实现简单的HttpServer服务器示例
2017/09/25 Python
Python实现的求解最小公倍数算法示例
2018/05/03 Python
Python面向对象程序设计构造函数和析构函数用法分析
2019/04/12 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
python中使用input()函数获取用户输入值方式
2020/05/03 Python
有关pycharm登录github时有的时候会报错connection reset的问题
2020/09/15 Python
在IE6系列等老式浏览器中使用HTML5的新标签实现方案
2012/12/25 HTML / CSS
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
工厂仓管员岗位职责
2014/01/01 职场文书
预备党员2014全国两会学习心得体会
2014/03/10 职场文书
向领导表决心的话
2014/03/11 职场文书
应届生求职自荐信
2014/07/04 职场文书
教师学习群众路线心得体会
2014/11/04 职场文书
横空出世观后感
2015/06/09 职场文书
民警忠诚教育心得体会
2016/01/23 职场文书
导游词之京东大峡谷旅游区
2019/10/29 职场文书
dubbo服务整合zipkin详解
2021/07/26 Java/Android
Javascript中async与await的捕捉错误详解
2022/03/03 Javascript