详解一个基于套接字实现长连接的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 相关文章推荐
学习YUI.Ext 第四天--对话框Dialog的使用
Mar 10 Javascript
JavaScript 工具库 Cloudgamer JavaScript Library v0.1 发布
Oct 29 Javascript
jQuery给元素添加样式的方法详解
Dec 30 Javascript
JQuery的Pager分页器实现代码
May 03 Javascript
微信小程序 仿猫眼实现实例代码
Mar 14 Javascript
基于JavaScript实现滑动门效果
Mar 16 Javascript
javascript 中的继承实例详解
May 05 Javascript
vue2.0多条件搜索组件使用详解
Mar 26 Javascript
JavaScript无操作后屏保功能的实现方法
Jul 04 Javascript
javascript 玩转Date对象(实例讲解)
Jul 11 Javascript
JS中封装axios来管控api的2种方式
Sep 11 Javascript
JavaScript canvas绘制折线图
Feb 18 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打造的tab选项卡效果代码(不用js)
2010/12/29 PHP
PHP中用正则表达式清除字符串的空白
2011/01/17 PHP
php自动载入类用法实例分析
2016/06/24 PHP
PHP简单预防sql注入的方法
2016/09/27 PHP
php in_array() 检查数组中是否存在某个值详解
2016/11/23 PHP
PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】
2017/02/07 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
js中reverse函数的用法详解
2013/12/26 Javascript
jQuery实现回车键(Enter)切换文本框焦点的代码实例
2014/05/05 Javascript
浅谈javascript回调函数
2014/12/07 Javascript
jQuery中fadeOut()方法用法实例
2014/12/24 Javascript
Vue.js组件tree实现无限级树形菜单
2016/12/02 Javascript
jQuery图片瀑布流的简单实现代码
2017/03/15 Javascript
Nodejs中使用captchapng模块生成图片验证码
2017/05/18 NodeJs
javascript 面向对象实战思想分享
2017/09/07 Javascript
浅谈JsonObject中的key-value数据解析排序问题
2017/12/06 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
2019/06/17 Javascript
在Vue中获取自定义属性方法:data-id的实例
2020/09/09 Javascript
JS实现超级好看的鼠标小尾巴特效
2020/12/01 Javascript
[01:55]2014DOTA2国际邀请赛 BBC正赛第一天总结
2014/07/10 DOTA
pandas DataFrame 警告(SettingWithCopyWarning)的解决
2019/07/23 Python
Django生成数据库及添加用户报错解决方案
2020/10/09 Python
Python3+SQLAlchemy+Sqlite3实现ORM教程
2021/02/16 Python
如何在网站上添加谷歌定位信息
2016/04/16 HTML / CSS
介绍一下SQL注入攻击的种类和防范手段
2012/02/18 面试题
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
大学生职业生涯规划范文
2013/12/31 职场文书
三年级数学教学反思
2014/01/31 职场文书
银行反四风对照检查材料
2014/09/29 职场文书
关于对大人不礼貌的检讨书
2014/09/29 职场文书
有限公司股东合作协议书
2014/10/29 职场文书
销售业务员岗位职责
2015/02/13 职场文书
六一晚会主持词开场白
2015/05/28 职场文书
2015年校医个人工作总结
2015/07/24 职场文书
2016年精神文明建设先进个人事迹材料
2016/02/29 职场文书
mysq启动失败问题及场景分析
2021/07/15 MySQL