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教程 安装express及配置app.js文件的详细步骤
May 11 NodeJs
nodejs 提示‘xxx’ 不是内部或外部命令解决方法
Nov 20 NodeJs
NodeJS中Buffer模块详解
Jan 07 NodeJs
用nodejs的实现原理和搭建服务器(动态)
Aug 10 NodeJs
nodejs读写json文件的简单方法(必看)
Mar 09 NodeJs
CentOS 安装NodeJS V8.0.0的方法
Jun 15 NodeJs
理解nodejs的stream和pipe机制的原理和实现
Aug 12 NodeJs
windows系统下更新nodejs版本的方案
Nov 24 NodeJs
nodejs实现简单的gulp打包
Dec 21 NodeJs
nodejs中express入门和基础知识点学习
Sep 13 NodeJs
详解从NodeJS搭建中间层再谈前后端分离
Nov 13 NodeJs
nodeJS进程管理器pm2的使用
Jan 09 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
PHP模块memcached使用指南
2014/12/08 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
php实现无限级分类(递归方法)
2015/08/06 PHP
PHP 5.6.11中CURL模块问题的解决方法
2016/08/08 PHP
PHP中的密码加密的解决方案总结
2016/10/26 PHP
PHP实现可精确验证身份证号码的工具类示例
2018/05/31 PHP
jquery中动态效果小结
2010/12/16 Javascript
javascript数字数组去重复项的实现代码
2010/12/30 Javascript
原生JS实现九宫格抽奖效果
2017/04/01 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
2020/06/29 Javascript
jQuery实现简单的计时器功能实例分析
2017/08/29 jQuery
bootstrap table合并行数据并居中对齐效果
2018/10/17 Javascript
[01:19:34]2014 DOTA2国际邀请赛中国区预选赛 New Element VS Dream time
2014/05/22 DOTA
[40:17]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第一场
2018/04/06 DOTA
用Python遍历C盘dll文件的方法
2015/05/06 Python
python获取当前用户的主目录路径方法(推荐)
2017/01/12 Python
Python使用base64模块进行二进制数据编码详解
2018/01/11 Python
Python分割指定页数的pdf文件方法
2018/10/26 Python
python 同时读取多个文件的例子
2019/07/16 Python
Windows下Pycharm远程连接虚拟机中Centos下的Python环境(图文教程详解)
2020/03/19 Python
如何导出python安装的所有模块名称和版本号到文件中
2020/06/05 Python
python+requests接口自动化框架的实现
2020/08/31 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
俄罗斯眼镜网: optikaworld
2016/07/31 全球购物
一加手机美国官方网站:OnePlus美国
2019/09/19 全球购物
斯洛伐克香水和化妆品购物网站:Parfemy-Elnino.sk
2020/01/28 全球购物
求职简历的自我评价怎样写好
2013/10/07 职场文书
如何撰写岗位职责
2014/02/01 职场文书
建筑结构施工专业推荐信
2014/02/21 职场文书
开业庆典主持词
2014/03/21 职场文书
幼儿园见习报告范文
2014/10/30 职场文书
2015年元旦晚会活动总结(学生会)
2014/11/28 职场文书
户外拓展训练感想
2015/08/07 职场文书
QT与javascript交互数据的实现
2021/05/26 Javascript
python识别围棋定位棋盘位置
2021/07/26 Python
Python中Numpy和Matplotlib的基本使用指南
2021/11/02 Python