详解一个基于套接字实现长连接的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 设计模式 推荐
Oct 28 Javascript
form表单action提交的js部分与html部分
Jan 07 Javascript
Javascript基础教程之while语句
Jan 18 Javascript
JavaScript实现将xml转换成html table表格的方法
Apr 17 Javascript
JQuery简单实现锚点链接的平滑滚动
May 03 Javascript
Bootstrap Fileinput文件上传组件用法详解
May 10 Javascript
jQuery 3.0中存在问题及解决办法
Jul 15 Javascript
浅析JavaScript中的array数组类型系统
Jul 18 Javascript
Angular 4依赖注入学习教程之简介(一)
Jun 04 Javascript
async/await地狱该如何避免详解
May 10 Javascript
vue打包之后生成一个配置文件修改接口的方法
Dec 09 Javascript
使用微信SDK自定义分享的方法
Jul 03 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使用百度天气接口示例
2014/04/22 PHP
PHP mkdir()无写权限的问题解决方法
2014/06/19 PHP
php中substr()函数参数说明及用法实例
2014/11/15 PHP
prototype Element学习笔记(篇二)
2008/10/26 Javascript
jquery异步调用页面后台方法&amp;#8207;(asp.net)
2011/03/01 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
2014/05/14 Javascript
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
JQuery在循环中绑定事件的问题详解
2016/06/02 Javascript
原生JS实现轮播效果+学前端的感受(防止走火入魔)
2016/08/21 Javascript
jQuery ajax MD5实现用户注册即时验证功能
2016/10/11 Javascript
JS非行间样式获取函数的实例代码
2018/06/05 Javascript
微信小程序自定义toast弹窗效果的实现代码
2018/11/15 Javascript
layDate插件设置开始和结束时间
2018/11/15 Javascript
js模拟实现烟花特效
2020/03/10 Javascript
在vue中实现给每个页面顶部设置title
2020/07/29 Javascript
[57:38]2018DOTA2亚洲邀请赛3月30日 小组赛A组 OpTic VS OG
2018/03/31 DOTA
[01:26]DOTA2荣耀之路2:iG,China
2018/05/24 DOTA
python计算时间差的方法
2015/05/20 Python
Python实现购物程序思路及代码
2017/07/24 Python
Python如何处理大数据?3个技巧效率提升攻略(推荐)
2019/04/15 Python
pyqt5使用按钮进行界面的跳转方法
2019/06/19 Python
深入了解Django View(视图系统)
2019/07/23 Python
Python3 使用pillow库生成随机验证码
2019/08/26 Python
使用html5制作loading图的示例
2014/04/14 HTML / CSS
英国运动服、设备及配件网站:DW Sports
2019/12/04 全球购物
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
工程造价专业求职信
2014/07/17 职场文书
优秀团员事迹材料1500字
2014/08/31 职场文书
工作总结与自我评价
2014/09/18 职场文书
邀请书模板
2015/02/02 职场文书
应届毕业生求职简历自我评价
2015/03/02 职场文书
教师见习总结范文
2015/06/23 职场文书
给校长的建议书作文500字
2015/09/14 职场文书
浅谈Python 中的复数问题
2021/05/19 Python
德生BCL3000抢先使用感受和评价
2022/04/07 无线电
彻底卸载VMware虚拟机的超详细步骤记录
2022/07/15 Servers