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链接Mysql做增删改查的简单操作
Feb 04 NodeJs
mac下的nodejs环境安装的步骤
May 24 NodeJs
nodejs创建简易web服务器与文件读写的实例
Sep 07 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
解决nodejs的npm命令无反应的问题
May 17 NodeJs
nodejs实现一个word文档解析器思路详解
Aug 14 NodeJs
nodejs实现日志读取、日志查找及日志刷新的方法分析
May 20 NodeJs
nodejs中实现用户注册路由功能
May 20 NodeJs
nodejs实现UDP组播示例方法
Nov 04 NodeJs
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
Nov 18 NodeJs
浅谈JS和Nodejs中的事件驱动
May 05 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检测图片木马多进制编程实践
2013/04/11 PHP
PHP编程入门的基本语法知识点总结
2016/01/26 PHP
Laravel中前端js上传图片到七牛云的示例代码
2017/09/04 PHP
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
javascript 写的一个简单的timer
2009/07/30 Javascript
google jQuery 引用文件,jQuery 引用地址集合(jquery 1.2.6至jquery1.5.2)
2011/04/24 Javascript
浅析JQuery UI Dialog的样式设置问题
2013/12/18 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
jQuery实现Email邮箱地址自动补全功能代码
2015/11/03 Javascript
jQuery 1.9.1源码分析系列(十三)之位置大小操作
2015/12/02 Javascript
jQuery遍历DOM的父级元素、子级元素和同级元素的方法总结
2016/07/07 Javascript
jQuery实现的表格展开伸缩效果实例
2016/09/07 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
2016/12/19 Javascript
深入理解Promise.all
2018/08/08 Javascript
layui-table获得当前行的上/下一行数据的例子
2019/09/24 Javascript
[00:55]深扒TI7聊天轮盘语音出处3
2017/05/11 DOTA
python实现斐波那契数列的方法示例
2017/01/12 Python
基于Python中单例模式的几种实现方式及优化详解
2018/01/09 Python
说说如何遍历Python列表的方法示例
2019/02/11 Python
Numpy之reshape()使用详解
2019/12/26 Python
PyQt5中向单元格添加控件的方法示例
2020/03/24 Python
Python如何在windows环境安装pip及rarfile
2020/06/15 Python
安装Anaconda3及使用Jupyter的方法
2020/10/27 Python
美国珠宝网上商店:Jeulia
2016/09/01 全球购物
欧洲顶级的童装奢侈品购物网站:Bambini Fashion(面向全球)
2018/04/24 全球购物
Vans奥地利官方网站:美国原创极限运动潮牌
2018/09/30 全球购物
Foot Locker英国官网:美国知名运动产品零售商
2019/02/21 全球购物
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
触发器(trigger)的功能都有哪些?写出一个触发器的例子
2012/09/17 面试题
通用求职信范文模板分享
2013/12/27 职场文书
竞选班委演讲稿
2014/04/28 职场文书
国旗下的讲话演讲稿
2014/05/08 职场文书
幼儿园老师个人总结
2015/02/28 职场文书
2014年个人总结范文
2015/03/09 职场文书
党员反邪教心得体会
2016/01/15 职场文书
Redis高级数据类型Hyperloglog、Bitmap的使用
2021/05/24 Redis