详解一个基于套接字实现长连接的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技巧
Dec 06 Javascript
IE6下opacity与JQuery的奇妙结合
Mar 01 Javascript
js为空或不是对象问题的快速解决方法
Dec 11 Javascript
JS cookie中文乱码解决方法
Jan 28 Javascript
node.js中的fs.chownSync方法使用说明
Dec 16 Javascript
JavaScript数组随机排列实现随机洗牌功能
Mar 19 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
JavaScript中的splice方法用法详解
Jul 20 Javascript
Three.js学习之正交投影照相机
Aug 01 Javascript
微信小程序 location API实例详解
Oct 02 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
Sep 12 Javascript
5个你不知道的JavaScript字符串处理库(小结)
Jun 01 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
Oracle 常见问题解答
2006/10/09 PHP
PHP IPV6正则表达式验证代码
2010/02/16 PHP
使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)
2014/05/05 PHP
thinkPHP学习笔记之安装配置篇
2015/03/05 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
php格式化时间戳
2016/12/17 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
优秀js开源框架-jQuery使用手册(1)
2007/03/10 Javascript
js优化针对IE6.0起作用(详细整理)
2012/12/25 Javascript
input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
2013/04/02 Javascript
用C/C++来实现 Node.js 的模块(二)
2014/09/24 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
jQuery学习笔记之jQuery中的$
2015/01/19 Javascript
JavaScript实现多个重叠层点击切换效果的方法
2015/04/24 Javascript
AngularJS基础 ng-keyup 指令简单示例
2016/08/02 Javascript
js通过classname来获取元素的方法
2016/11/24 Javascript
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
2018/10/29 Javascript
用Python抢过年的火车票附源码
2015/12/07 Python
Django基于ORM操作数据库的方法详解
2018/03/27 Python
详解如何用django实现redirect的几种方法总结
2018/11/22 Python
pyshp创建shp点文件的方法
2018/12/31 Python
Python assert关键字原理及实例解析
2019/12/13 Python
python3实现raspberry pi(树莓派)4驱小车控制程序
2020/02/12 Python
python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例
2020/03/08 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
python 偷懒技巧——使用 keyboard 录制键盘事件
2020/09/21 Python
使用Python解析Chrome浏览器书签的示例
2020/11/13 Python
Python Pygame实现俄罗斯方块
2021/02/19 Python
英国空调、除湿机和通风设备排名第一:Air Con Centre
2019/02/25 全球购物
应用化学专业职业生涯规划书
2014/01/22 职场文书
个人主要事迹材料
2014/08/26 职场文书
感谢信范文大全
2015/01/23 职场文书
校运会广播稿
2015/08/19 职场文书
一篇文章弄懂Python中的内建函数
2021/08/07 Python
如何Python使用re模块实现okenizer
2022/04/30 Python