详解一个基于套接字实现长连接的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 相关文章推荐
Extjs优化(一)删除冗余代码提高运行速度
Apr 15 Javascript
Jquery事件的连接使用示例
Jun 18 Javascript
jquery重新播放css动画所遇问题解决
Aug 21 Javascript
node.js中的console.log方法使用说明
Dec 09 Javascript
javascript检测两个数组是否相似
May 19 Javascript
JS简单测试循环运行时间的方法
Sep 04 Javascript
AngularJS 实现JavaScript 动画效果详解
Sep 08 Javascript
关于JavaScript和jQuery的类型判断详解
Oct 08 Javascript
jQuery EasyUI开发技巧总结
Sep 26 jQuery
一个简单的node.js界面实现方法
Jun 01 Javascript
tweenjs缓动算法的使用实例分析
Aug 26 Javascript
原生js+css实现tab切换功能
Sep 17 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 park、unpark、ord 函数使用方法(二进制流接口应用实例)
2010/10/19 PHP
php调用mysql数据 dbclass类
2011/05/07 PHP
PHP filter_var() 函数 Filter 函数
2012/04/25 PHP
php版淘宝网查询商品接口代码示例
2014/06/17 PHP
php不使用copy()函数复制文件的方法
2015/03/13 PHP
PHP用mb_string函数库处理与windows相关中文字符及Win环境下开启PHP Mb_String方法
2015/11/11 PHP
浅谈PHP中的
2016/04/23 PHP
PHP实现限制IP访问及提交次数的方法详解
2017/07/17 PHP
php魔法函数与魔法常量使用介绍
2017/07/23 PHP
JavaScript 组件之旅(一)分析和设计
2009/10/28 Javascript
jQuery EasyUI API 中文文档 搜索框
2011/09/29 Javascript
如何将网页表格内容导入excel
2014/02/18 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
JavaScript实现的简单幂函数实例
2015/04/17 Javascript
浅析JavaScript中的事件机制
2015/06/04 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
2016/07/21 Javascript
JS实现禁止鼠标右键的功能
2016/10/15 Javascript
jQuery实现拖拽可编辑模块功能代码
2017/01/12 Javascript
JavaScript运行原理分析
2018/02/09 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
2018/06/04 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
2019/04/13 Javascript
微信公众号生成新浪短网址的实现(快速生成)
2019/08/18 Javascript
用Django写天气预报查询网站
2018/10/21 Python
Python 绘制酷炫的三维图步骤详解
2019/07/12 Python
np.newaxis 实现为 numpy.ndarray(多维数组)增加一个轴
2019/11/30 Python
Python如何省略括号方法详解
2020/03/21 Python
Python改变对象的字符串显示的方法
2020/08/01 Python
PyQt实现计数器的方法示例
2021/01/18 Python
使用canvas一步步实现图片打码功能的方法
2019/06/17 HTML / CSS
Gretna Green中文官网:苏格兰格林小镇
2019/10/16 全球购物
PHP面试题及答案一
2012/06/18 面试题
经营目标管理责任书
2014/07/25 职场文书
三八妇女节趣味活动方案
2014/08/23 职场文书
在校生证明
2015/06/17 职场文书
关于践行三严三实的心得体会
2016/01/05 职场文书
详解mysql三值逻辑与NULL
2021/05/19 MySQL