详解一个基于套接字实现长连接的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的live使用注意事项
Feb 18 Javascript
JS判断变量是否为空判断是否null
Jul 25 Javascript
js时间日期格式化封装函数
Dec 02 Javascript
javascript使用call调用微信API
Dec 15 Javascript
jQuery点击输入框显示验证码图片
May 19 Javascript
Bootstrap Metronic完全响应式管理模板之菜单栏学习笔记
Jul 08 Javascript
基于jQuery实现简单人工智能聊天室
Feb 10 Javascript
Angular.js中angular-ui-router的简单实践
Jul 18 Javascript
vue组件实现进度条效果
Jun 06 Javascript
Vue.js实现双向数据绑定方法(表单自动赋值、表单自动取值)
Aug 27 Javascript
微信小程序登录session的使用
Mar 17 Javascript
Node.js设置定时任务之node-schedule模块的使用详解
Apr 28 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中改变图片的尺寸大小的代码
2011/07/17 PHP
php中使用临时表查询数据的一个例子
2013/02/03 PHP
PHP常量使用的几个需要注意的地方(谨慎使用PHP中的常量)
2014/09/12 PHP
PHP file_get_contents函数读取远程数据超时的解决方法
2015/05/13 PHP
基于PHP如何把汉字转化为拼音
2015/12/11 PHP
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
javascript算法学习(直接插入排序)
2011/04/12 Javascript
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
使用documentElement正确取得当前可见区域的大小
2014/07/25 Javascript
png在IE6 下无法透明的解决方法汇总
2015/05/21 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
JavaScript小技巧整理
2015/12/30 Javascript
jQuery文件上传控件 Uploadify 详解
2016/06/20 Javascript
TypeScript入门-基本数据类型
2017/03/28 Javascript
详解angularJS+Ionic移动端图片上传的解决办法
2017/09/13 Javascript
npm 下载指定版本的组件方法
2018/05/17 Javascript
vue如何自动化打包测试环境和正式环境的dist/test文件
2019/06/06 Javascript
vue实现页面内容禁止选中功能,仅输入框和文本域可选
2019/11/09 Javascript
JavaScript 实现拖拽效果组件功能(兼容移动端)
2020/11/11 Javascript
Python中操作mysql的pymysql模块详解
2016/09/13 Python
python环形单链表的约瑟夫问题详解
2018/09/27 Python
基于python指定包的安装路径方法
2018/10/27 Python
Python设计模式之组合模式原理与用法实例分析
2019/01/11 Python
在python中画正态分布图像的实例
2019/07/08 Python
基于python的列表list和集合set操作
2019/11/24 Python
在pytorch中实现只让指定变量向后传播梯度
2020/02/29 Python
python如何设置静态变量
2020/09/07 Python
安装并免费使用Pycharm专业版(学生/教师)
2020/09/24 Python
详解Python爬虫爬取博客园问题列表所有的问题
2021/01/18 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
2021/03/04 Python
详解html5页面 rem 布局适配方法
2018/01/12 HTML / CSS
压铸汽车模型收藏家:Diecastmodelswholesale.com
2016/12/21 全球购物
2014年公务员转正工作总结
2014/11/07 职场文书
2015年设计师个人工作总结
2015/04/25 职场文书
美丽的大脚观后感
2015/06/03 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书