详解一个基于套接字实现长连接的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 内存回收机制理解
Jan 17 Javascript
javascript设置连续两次点击按钮时间间隔的方法
Oct 28 Javascript
浅谈javascript的Touch事件
Sep 27 Javascript
基于JS实现textarea中获取动态剩余字数的方法
May 25 Javascript
Bootstrap编写一个在当前网页弹出可关闭的对话框 非弹窗
Jun 30 Javascript
AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法
Dec 14 Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
Jan 19 Javascript
解决Jquery下拉框数据动态获取的问题
Jan 25 jQuery
angularJS1 url中携带参数的获取方法
Oct 09 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
May 28 jQuery
微信小程序scroll-view锚点链接滚动跳转功能
Dec 12 Javascript
原生js实现自定义消息提示框
Nov 19 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中数组定义的几种方法
2013/09/01 PHP
php类常量用法实例分析
2015/07/09 PHP
PHP代码维护,重构变困难的4种原因分析
2016/01/25 PHP
自己整理的一个javascript日期处理函数
2010/10/16 Javascript
jQuery控制图片的hover效果(smartRollover.js)
2012/03/18 Javascript
Jquery的Tabs内容轮换效果实现代码,几行搞定
2014/02/12 Javascript
javascript消除window.close()的提示窗口
2015/05/20 Javascript
将页面table内容与样式另存成excel文件的方法
2015/08/05 Javascript
Bootstrap基本插件学习笔记之标签切换(17)
2016/12/08 Javascript
AngularJS通过ng-Img-Crop实现头像截取的示例
2017/08/17 Javascript
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
2017/09/18 NodeJs
vue微信分享 vue实现当前页面分享其他页面
2017/12/02 Javascript
简单的React SSR服务器渲染实现
2018/12/11 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
2019/12/10 Javascript
Vuex实现数据共享的方法
2019/12/20 Javascript
Python3访问并下载网页内容的方法
2015/07/28 Python
python logging 日志轮转文件不删除问题的解决方法
2016/08/02 Python
PyQt5每天必学之单行文本框
2018/04/19 Python
python+selenium实现自动抢票功能实例代码
2018/11/23 Python
pandas分批读取大数据集教程
2020/06/06 Python
10 套华丽的CSS3 按钮小结
2012/10/03 HTML / CSS
CSS3 清除浮动的方法示例
2018/06/01 HTML / CSS
HTML5组件Canvas实现图像灰度化(步骤+实例效果)
2013/04/22 HTML / CSS
eBay爱尔兰站:eBay.ie
2019/08/09 全球购物
仪器仪表检测毕业生自荐信
2013/10/31 职场文书
汽车专业毕业生自荐信
2013/11/03 职场文书
公司成本主管岗位责任制
2014/02/21 职场文书
班级寄语大全
2014/04/10 职场文书
2014年综治宣传月活动总结
2014/04/28 职场文书
信息合作协议书
2014/10/09 职场文书
2015年社区居委会工作总结
2015/05/18 职场文书
2016党校学习心得体会范文
2016/01/07 职场文书
如何正确理解python装饰器
2021/06/15 Python
yolov5返回坐标的方法实例
2022/03/17 Python
Java设计模式中的命令模式
2022/04/28 Java/Android
Python使用Beautiful Soup(BS4)库解析HTML和XML
2022/06/05 Python