NodeJs 模仿SIP话机注册的方法


Posted in NodeJs onJune 21, 2019

本项目需要对应的后端接口、信令环境才能正常运行,本文章只涉及前端内容。

项目依赖模块:

  • NodeJs
  • readline:命令行输入
  • ws:与服务端建立websocket连接
  • superagent:与服务端建立请求连接,效果类似ajax请求
  • tsk_md5:项目登录密码使用MD5加密

项目需求

模拟SIP话机频繁向服务器发起注册请求,以得到服务器最大SIP注册数

项目实现概述

  1. 终端输入连续注册分机的开始分机号和结束分机号
  2. 终端输入统一的SIP注册密码
  3. 终端输入服务器地址
  4. 先进行用户登录鉴权,用户登录鉴权通过后再发起SIP注册

代码分析

1. 引入项目所需模块

var WebSocket = require('ws'),
 superagent = require('superagent'),
 tskMD5 = require('./tsk_md5')
 const readline = require('readline');

2. 创建readline 接口实例

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: 'OHAI> '
 });

3. 定义所需变量

var obj = {}, httpHeader = {}, baseUrl ='', pass = '', ip = '', websocketUrl = ''
var keepWsAlive, readyState

4. 读取readline 输入信息函数

function getReadline() {
 const lines = []; // 用于保存所有输入信息。
 console.log('Please input the range of extensions(eg: 1001,1010):\n')
 rl.on("line", function(line) {
  if (line ==='') {
   console.log('The input is empty, please input again:\n')
  } else {
   lines.push(line);
   if (lines.length === 1) {
    obj.extensionsArr = line.split(',');
    console.log('Please input the password(eg:1234aa):\n')
   } else if (lines.length === 2) {
    obj.password = line;
    pass = line;
    console.log('Please input the ip(eg:192.168.124.125):\n')
   } else if (lines.length === 3) {
    websocketUrl = 'ws://' + line + ':8089/ws';
    obj.websocketUrl = websocketUrl;
    obj.ip = line;
    ip = line;
    console.log('Starting register...\n');
    // 开始注册事件
    loopRegister(obj) 
   }
  }
 });
 
 // close事件监听
 rl.on("close", function(){
  // 结束程序
  process.exit(0);
 });
 }

终端运行截图

NodeJs 模仿SIP话机注册的方法 

5.注册事件中包含几个动作

1)设置httpHeader:浏览器与服务器ajax请求有固定的请求头信息,此处模拟浏览器的请求头信息。

用于后续发送请求进行用户登录鉴权。

function setHttpHeader(username) {
  httpHeader = {
   Accept:'application/json, text/javascript, */*; q=0.01',
   'Accept-Encoding': 'gzip, deflate',
   'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,pt;q=0.7',
   'Cache-Control': 'no-cache',
   Connection: 'keep-alive',
   'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
   Cookie: 'TRACKID='+trackid+'; session-identify=sid121076289-1520217430; username=admin; user_id=0',
   Host: ip +':8089',
   Origin: 'http://'+ip+':8089',
   Pragma: 'no-cache',
   Referer: 'http://'+ip+':8089/gswave/',
   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0',
   'X-Requested-With':'XMLHttpRequest'
  }
  var accountData = {
   action:'challenge',
   user:username
  }
  baseUrl = 'http://'+ip+':8089/webrtccgi?';
  getChanllenge(accountData, username) // 用户鉴权函数
 }

2)用户登录鉴权(本项目中与服务器交互需要使用,具体使用看服务器端设置)

<!--账号密码 鉴权-->
function getChanllenge(accountData, username) {
  console.log('start getChangllenge')
  var challenge = ''
  //获取challenge
   superagent
    .post(baseUrl)
    .set(httpHeader)
    .type('form')
    .send(accountData)
    .redirects(0)
    .end(function(err, result) {
     if (typeof(result) == 'undefined') {
      console.error("get challenge is error, result is undefined");
     } else {
      var responce = result.body
      if(responce && responce.status === 0) {
       challenge = responce.response.challenge
       getCookie(challenge, username)
      } else {
       console.error('get challenge is error, result.body.status is not 0')
      }
     }
    });
 }

 <!--cookie 鉴权-->
 
 function getCookie(challenge, username) {
  var md5key = tskMD5.MD5.hexdigest(challenge + pass) // MD5加密用户登录密码
  var subData={
   token: md5key,
   action: 'login',
   user: username
  }
  // 开始请求进行用户登录密码鉴权,类似ajax请求
  superagent
   .post(baseUrl)
   .set(httpHeader)
   .type('form')
   .send(subData)
   .redirects(0)
   .end(function(err, res) {
    if (typeof(res) == 'undefined') {
     console.log("get cookie is error, result is undefined");
    } else {
     var responce = res.body
     if(responce && responce.status === 0) {
     // 登录鉴权通过,开始执行SIP注册
      var cookie = responce.response.cookie
      // 注册函数
      startSocket(username)
     } else {
      console.log('get cookie is error, result.body.status is not 0')
     }
    }
   })
 }

与服务器建立websocket连接

项目中信令交互信息均通过websocket发送

var ws = new WebSocket(websocketUrl, "sip"); # 注意建立的是sip类型的websocket

 ws.on('open', function open() {
  console.log('ws open message1' + message1)
  readyState = WebSocket.OPEN
  // 发送相关信息
  ws.send(message); 
 });
 
 ws.on('message', function incoming(data) {
  a++;
  var dataArr = data.split('\r\n')
  if (dataArr[0].indexOf('401') > -1 && a === 1) {
   // 发送注册信令函数(其中发送信令信息,均参考浏览器的发送头进行拼接)
   startRegister(ws, dataArr, username)
  } else if (dataArr[0].indexOf('200')) {
   // ws.close()
   // console.log('register sucess...')
  } else {
  }
 });

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
nodejs 后缀名判断限制代码
Mar 31 NodeJs
nodejs读取memcache示例分享
Jan 02 NodeJs
NodeJS实现阿里大鱼短信通知发送
Jan 17 NodeJs
NodeJS的Promise的用法解析
May 05 NodeJs
nodejs个人博客开发第六步 数据分页
Apr 12 NodeJs
nodejs multer实现文件上传与下载
May 10 NodeJs
nodejs实现截取上传视频中一帧作为预览图片
Dec 10 NodeJs
nodejs使用http模块发送get与post请求的方法示例
Jan 08 NodeJs
nodejs简单访问及操作mysql数据库的方法示例
Mar 15 NodeJs
nodejs 日志模块winston的使用方法
May 02 NodeJs
nodeJS服务器的创建和重新启动的实现方法
May 12 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
通过Nodejs搭建网站简单实现注册登录流程
Jun 14 #NodeJs
NodeJs生成sitemap站点地图的方法示例
Jun 11 #NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 #NodeJs
Nodejs异步流程框架async的方法
Jun 07 #NodeJs
nodejs log4js 使用详解
May 31 #NodeJs
如何让Nodejs支持H5 History模式(connect-history-api-fallback源码分析)
May 30 #NodeJs
nodejs中实现修改用户路由功能
May 24 #NodeJs
You might like
Thinkphp将二维数组变为标签适用的一维数组方法总结
2014/10/30 PHP
PHP内核学习教程之php opcode内核实现
2016/01/27 PHP
php版交通银行网银支付接口开发入门教程
2016/09/26 PHP
PHP中for循环与foreach的区别
2017/03/06 PHP
网页上的Javascript编辑器和代码格式化
2010/04/25 Javascript
JQuery 操作select标签实现代码
2010/05/14 Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
2011/04/12 Javascript
基于jQuery的360图片展示实现代码
2012/06/14 Javascript
jQuery处理图片加载失败的常用方法
2015/06/08 Javascript
js窗口关闭提示信息(兼容IE和firefox)
2015/10/23 Javascript
angular基于路由控制ui-router实现系统权限控制
2016/09/27 Javascript
Vue组件开发初探
2017/02/14 Javascript
JS自定义滚动条效果简单实现代码
2020/10/27 Javascript
Hexo已经看腻了,来手把手教你使用VuePress搭建个人博客
2018/04/26 Javascript
关于vue v-for 循环问题(一行显示四个,每一行的最右边那个计算属性)
2018/09/04 Javascript
详解关于Vuex的action传入多个参数的问题
2019/02/22 Javascript
Swiper.js实现移动端元素左右滑动
2019/09/08 Javascript
[01:13]DOTA2群星解读国服召集令 一起说出回归的理由
2013/07/17 DOTA
[03:11]完美世界DOTA2联赛PWL DAY8集锦
2020/11/09 DOTA
[47:31]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.12
2020/12/16 DOTA
python实现的简单抽奖系统实例
2015/05/22 Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
2018/02/11 Python
python获取响应某个字段值的3种实现方法
2020/04/30 Python
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
Kate Spade美国官网:纽约新兴时尚品牌,以包包闻名于世
2017/11/09 全球购物
俄罗斯便宜的在线服装商店:GroupPrice
2020/04/10 全球购物
德国W家官网,可直邮中国的母婴商城:Windeln.de
2021/03/03 全球购物
医学实习生自我鉴定
2013/12/12 职场文书
物业门卫岗位职责
2013/12/28 职场文书
卫校中专生的自我评价
2014/01/15 职场文书
工作建议书范文
2014/05/13 职场文书
2016年暑期见闻作文
2015/11/25 职场文书
2016年大学光棍节活动总结
2016/04/05 职场文书
mysql死锁和分库分表问题详解
2021/04/16 MySQL
关于antd tree 和父子组件之间的传值问题(react 总结)
2021/06/02 Javascript
uni-app 微信小程序授权登录的实现步骤
2022/02/18 Javascript