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中自定义事件实例
Jun 20 NodeJs
NodeJS学习笔记之FS文件模块
Jan 13 NodeJs
nodejs事件的监听与触发的理解分析
Feb 12 NodeJs
nodejs中实现sleep功能实例
Mar 24 NodeJs
windows下安装nodejs及框架express
Aug 07 NodeJs
nodejs个人博客开发第六步 数据分页
Apr 12 NodeJs
nodejs批量下载图片的实现方法
May 19 NodeJs
基于Nodejs的Tcp封包和解包的理解
Sep 19 NodeJs
深入理解NodeJS 多进程和集群
Oct 17 NodeJs
nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法
Nov 01 NodeJs
Nodejs对postgresql基本操作的封装方法
Feb 20 NodeJs
nodejs微信开发之自动回复的实现
Mar 17 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中的字符编码转换函数用法示例
2014/10/20 PHP
smarty高级特性之对象的使用方法
2015/12/25 PHP
对比PHP对MySQL的缓冲查询和无缓冲查询
2016/07/01 PHP
CL vs ForZe BO5 第四场 2.13
2021/03/10 DOTA
很可爱的输入框
2008/08/03 Javascript
javascript常用对话框小集
2013/09/13 Javascript
键盘KeyCode值列表汇总
2013/11/26 Javascript
js星星评分效果
2014/07/24 Javascript
jquery带下拉菜单和焦点图代码分享
2015/08/24 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
2015/09/22 Javascript
js实现表单及时验证功能 用户信息立即验证
2016/09/13 Javascript
详解ES6中的let命令
2020/04/05 Javascript
js实现五星评价功能
2017/03/08 Javascript
用vue 实现手机触屏滑动功能
2020/05/28 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
2020/10/28 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
2020/11/26 Vue.js
python去掉 unicode 字符串前面的u方法
2018/10/21 Python
python实现将文件夹下面的不是以py文件结尾的文件都过滤掉的方法
2018/10/21 Python
Python补齐字符串长度的实例
2018/11/15 Python
Django 模型类(models.py)的定义详解
2019/07/19 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
基于SpringBoot构造器注入循环依赖及解决方式
2020/04/26 Python
详解移动端HTML5页面端去掉input输入框的白色背景和边框(兼容Android和ios)
2016/12/15 HTML / CSS
详解基于canvas的视频遮罩插件
2018/01/04 HTML / CSS
康帕斯酒店预订:Compass Hospitality(支持中文)
2018/08/23 全球购物
有原因的手表:Flex Watches
2019/03/23 全球购物
超级英雄、电影和电视、乐队和音乐T恤:Loud Clothing
2019/09/01 全球购物
上级检查欢迎词
2014/01/18 职场文书
教师绩效考核方案
2014/01/21 职场文书
优秀志愿者事迹材料
2014/02/03 职场文书
秸秆管理实施方案
2014/03/15 职场文书
最新优秀教师个人先进事迹材料
2014/05/06 职场文书
2015年社区精神文明工作总结
2015/05/26 职场文书
六五普法先进个人主要事迹材料
2015/11/03 职场文书
实习报告怎么写
2019/06/20 职场文书
mysql如何查询连续记录
2022/05/11 MySQL