详解一个基于套接字实现长连接的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匿名函数应用示例介绍
Mar 07 Javascript
jquery对table中各数据的增加、保存、删除操作示例
May 14 Javascript
分享2个jQuery插件--jquery.fileupload与artdialog
Dec 26 Javascript
jQuery中delegate()方法的用法详解
Oct 13 Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
Feb 13 Javascript
ES5 ES6中Array对象去除重复项的方法总结
Apr 27 Javascript
JavaScript原型式继承实现方法
Nov 06 Javascript
使用JS location实现搜索框历史记录功能
Dec 23 Javascript
vue中实现动态生成二维码的方法
Feb 21 Javascript
Vue移动端项目实现使用手机预览调试操作
Jul 18 Javascript
解决vue 使用axios.all()方法发起多个请求控制台报错的问题
Nov 09 Javascript
原生JavaScript实现留言板
Jan 10 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
Windows下PHP5和Apache的安装与配置
2006/09/05 PHP
Nigma vs Liquid BO3 第一场2.13
2021/03/10 DOTA
javascript重写alert方法的实例代码
2013/03/29 Javascript
JS 两个字符串时间的天数差计算
2013/08/25 Javascript
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
JavaScript 异常处理 详解
2015/02/06 Javascript
基于WebUploader的文件上传js插件
2016/08/19 Javascript
原生JS实现图片轮播与淡入效果的简单实例
2016/08/21 Javascript
Javascript获取图片原始宽度和高度的方法详解
2016/09/20 Javascript
jQuery插件扩展实例【添加回调函数】
2016/11/26 Javascript
浅谈jQuery中的$.extend方法来扩展JSON对象
2017/02/12 Javascript
nodejs+express实现文件上传下载管理网站
2017/03/15 NodeJs
微信小程序页面传值实例分析
2017/04/19 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
vue: WebStorm设置快速编译运行的方法
2018/10/18 Javascript
微信小程序中的canvas 文字断行和省略号显示功能的处理方法
2018/11/14 Javascript
一次让你了解全部JavaScript的作用域
2019/06/24 Javascript
Node.js开发之套接字(socket)编程入门示例
2019/11/05 Javascript
vue element 中的table动态渲染实现(动态表头)
2019/11/21 Javascript
浅谈pandas中Dataframe的查询方法([], loc, iloc, at, iat, ix)
2018/04/10 Python
python实现学员管理系统
2019/02/26 Python
在python image 中安装中文字体的实现方法
2019/08/22 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
tensorflow 自定义损失函数示例代码
2020/02/05 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
2020/04/01 Python
英国珠宝网站Argento: PANDORA、Olivia Burton和Nomination等
2020/05/08 全球购物
为什么要使用servlet
2016/01/17 面试题
高三毕业寄语
2014/04/10 职场文书
党员先锋岗事迹材料
2014/05/08 职场文书
红色故事演讲稿
2014/05/22 职场文书
2014房屋登记授权委托书
2014/10/13 职场文书
大学生社会实践活动总结报告
2015/05/06 职场文书
丧事酒宴答谢词
2015/09/30 职场文书
python中的random模块和相关函数详解
2022/04/22 Python
Java版 单机五子棋
2022/05/04 Java/Android
apache ftpserver搭建ftp服务器
2022/05/20 Servers