详解一个基于套接字实现长连接的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 相关文章推荐
jQuery 选择器理解
Mar 16 Javascript
js使用函数绑定技术改变事件处理程序的作用域
Dec 26 Javascript
js实现匹配时换色的输入提示特效代码
Aug 17 Javascript
jquery实现适用于门户站的导航下拉菜单效果代码
Aug 24 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
Aug 01 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
Nov 22 Javascript
js+canvas实现动态吃豆人效果
Mar 22 Javascript
JS排序之快速排序详解
Apr 08 Javascript
angular 实时监听input框value值的变化触发函数方法
Aug 31 Javascript
Vue入门之数量加减运算操作示例
Dec 11 Javascript
vue data引入本地图片的两种方式小结
Nov 13 Javascript
通过实例解析vuejs如何实现调试代码
Jul 16 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
阿拉伯的咖啡与水烟
2021/03/03 咖啡文化
frename PHP 灵活文件命名函数 frename
2009/09/09 PHP
Yii学习总结之数据访问对象 (DAO)
2015/02/22 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
DWZ+ThinkPHP开发时遇到的问题分析
2016/12/12 PHP
PHP微信网页授权的配置文件操作分析
2019/05/29 PHP
laravel框架使用阿里云短信发送消息操作示例
2020/02/15 PHP
Prototype Function对象 学习
2009/07/12 Javascript
js的压缩及jquery压缩探讨(提高页面加载性能/保护劳动成果)
2013/01/29 Javascript
jQuery 借助插件Lavalamp实现导航条动态美化效果
2013/09/27 Javascript
js实现图片在未加载完成前显示加载中字样
2014/09/03 Javascript
jQuery晃动层特效实现方法
2015/03/09 Javascript
jQuery中判断对象是否存在的方法汇总
2016/02/24 Javascript
jQuery实现订单提交页发送短信功能前端处理方法
2016/07/04 Javascript
Web安全测试之XSS实例讲解
2016/08/15 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
2016/09/05 Javascript
JavaScript获取服务器端时间的方法
2016/11/29 Javascript
基于JavaScript实现数码时钟效果
2020/03/30 Javascript
BootStrap的双日历时间控件使用
2017/07/25 Javascript
Vertx基于EventBus发送接受自定义对象
2020/11/16 Javascript
pandas数据分组和聚合操作方法
2018/04/11 Python
python爬虫实现中英翻译词典
2019/06/25 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
2020/02/17 Python
Pycharm操作Git及GitHub的步骤详解
2020/10/27 Python
实例讲解CSS3中的border-radius属性
2015/08/18 HTML / CSS
Gloeilampgoedkoop荷兰:在线购买灯泡
2019/02/16 全球购物
JAVA和C++区别都有哪些
2015/03/30 面试题
缴纳养老保险的证明
2014/01/10 职场文书
档案接收函范文
2014/01/10 职场文书
个人简历中的自我评价怎么写
2014/01/26 职场文书
计算机毕业生求职信
2014/06/10 职场文书
怎样写离婚协议书
2014/09/10 职场文书
2015年教师节感恩寄语
2015/03/23 职场文书
团组织推荐意见
2015/06/05 职场文书
礼貌问候语大全
2015/11/10 职场文书
灵能百分百第三季什么时候来?
2022/03/15 日漫