详解一个基于套接字实现长连接的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 相关文章推荐
xmlHTTP实例
Oct 24 Javascript
javascript 函数使用说明
Apr 07 Javascript
js构造函数、索引数组和属性的实现方式和使用
Nov 16 Javascript
JavaScript设计模式之装饰者模式介绍
Dec 28 Javascript
javascript实现密码强度显示
Mar 18 Javascript
JavaScript中用于生成随机数的Math.random()方法
Jun 15 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
Aug 08 Javascript
jQuery插件JWPlayer视频播放器用法实例分析
Jan 11 Javascript
JavaScript登录记住密码操作(超简单代码)
Mar 22 Javascript
JavaScript设计模式之建造者模式实例教程
Jul 02 Javascript
解决vue更新路由router-view复用组件内容不刷新的问题
Nov 04 Javascript
JavaScript复制变量三种方法实例详解
Jan 09 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通过array_merge()函数合并两个数组的方法
2015/03/18 PHP
php实现的三个常用加密解密功能函数示例
2017/11/06 PHP
解决Laravel5.2 Auth认证退出失效的问题
2019/10/14 PHP
文字幻灯片
2006/06/26 Javascript
仿163填写邮件地址自动显示下拉(无优化)
2008/11/05 Javascript
Javascript操作URL函数修改版
2013/11/07 Javascript
js实现刷新iframe的方法汇总
2015/04/27 Javascript
基于JS实现密码框(password)中显示文字提示功能代码
2016/05/27 Javascript
AngularJS ng-bind-template 指令详解
2016/07/30 Javascript
Javascript 跨域知识详细介绍
2016/10/30 Javascript
Bootstrap源码解读下拉菜单(4)
2016/12/23 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
2018/04/09 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
javascript原型链学习记录之继承实现方式分析
2019/05/01 Javascript
vue prop属性传值与传引用示例
2019/11/13 Javascript
Python功能键的读取方法
2015/05/28 Python
python编程使用selenium模拟登陆淘宝实例代码
2018/01/25 Python
python使用time、datetime返回工作日列表实例代码
2019/05/09 Python
python爬虫项目设置一个中断重连的程序的实现
2019/07/26 Python
基于python 微信小程序之获取已存在模板消息列表
2019/08/05 Python
python输入错误后删除的方法
2019/10/12 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
2019/11/19 Python
python标准库OS模块函数列表与实例全解
2020/03/10 Python
基于nexus3配置Python仓库过程详解
2020/06/15 Python
python上下文管理的使用场景实例讲解
2021/03/03 Python
美国领先的水果篮送货公司和新鲜水果供应商:The Fruit Company
2018/02/13 全球购物
如何配置、使用和清除Smarty缓存
2015/12/23 面试题
十八届三中全会宣传方案
2014/02/21 职场文书
入职担保书怎么写
2014/05/12 职场文书
诚信承诺书模板
2014/05/26 职场文书
单身证明格式样本
2015/06/15 职场文书
安全教育片观后感
2015/06/17 职场文书
小学数学国培研修日志
2015/11/13 职场文书
Android Studio实现简易进制转换计算器
2022/05/20 Java/Android
Python+pyaudio实现音频控制示例详解
2022/07/23 Python