详解一个基于套接字实现长连接的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 相关文章推荐
通过修改referer下载文件的方法
May 11 Javascript
JavaScript面向对象(极简主义法minimalist approach)
Jul 17 Javascript
使用javascipt---实现二分查找法
Apr 10 Javascript
从数据库读取数据后将其输出成html标签的三种方法
Oct 13 Javascript
全面解析Bootstrap弹窗的实现方法
Dec 01 Javascript
基于bootstrap按钮式下拉菜单组件的搜索建议插件
Mar 25 Javascript
JS实现的视频弹幕效果示例
Aug 17 Javascript
vue移动端微信授权登录插件封装的实例
Aug 28 Javascript
vue填坑之webpack run build 静态资源找不到的解决方法
Sep 03 Javascript
Bootstrap4 gulp 配置详解
Jan 06 Javascript
手把手15分钟搭一个企业级脚手架
Sep 16 Javascript
JavaScript如何借用构造函数继承
Nov 06 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中static关键字原理的学习研究分析
2011/07/18 PHP
thinkphp实现面包屑导航(当前位置)例子分享
2014/05/10 PHP
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
JS常见问题整理(持续更新)
2013/08/06 Javascript
Js实现手机发送验证码时按钮延迟操作
2014/06/20 Javascript
js解决select下拉选不中问题
2014/10/14 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
2015/03/04 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
AngularJS中的指令全面解析(必看)
2016/05/20 Javascript
jQuery表单元素选择器代码实例
2017/02/06 Javascript
JavaScript实现的鼠标响应颜色渐变效果完整实例
2017/02/18 Javascript
js实现下拉菜单效果
2017/03/01 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
2017/04/25 Javascript
jQuery模拟实现天猫购物车动画效果实例代码
2017/05/25 jQuery
JavaScript实现选中文字提示新浪微博分享效果
2017/06/15 Javascript
jQuery菜单实例(全选,反选,取消)
2017/08/28 jQuery
bootstrap日期插件daterangepicker使用详解
2017/10/19 Javascript
AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断后添加表格信息)
2017/10/24 Javascript
浅谈Vuex的状态管理(全家桶)
2017/11/04 Javascript
Angular6笔记之封装http的示例代码
2018/07/27 Javascript
vue组件中的样式属性scoped实例详解
2018/10/30 Javascript
微信小程序缓存过期时间的使用详情
2019/05/12 Javascript
Vue2.x通用条件搜索组件的封装及应用详解
2019/05/28 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
使用XML库的方式,实现RPC通信的方法(推荐)
2017/06/14 Python
Python3实现的回文数判断及罗马数字转整数算法示例
2019/03/27 Python
深入了解如何基于Python读写Kafka
2019/12/31 Python
python里glob模块知识点总结
2021/01/05 Python
利用三角函数在canvas上画虚线的方法
2018/01/11 HTML / CSS
英国排名第一的LED灯泡网站:LED Bulbs
2019/09/03 全球购物
慈善捐赠倡议书
2014/08/30 职场文书
离婚协议书怎么写(范本参考)
2014/09/30 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS
Oracle使用别名的好处
2022/04/19 Oracle