JsSIP和FreeSWITCH整合

写在前面:FreeSWITCH作为服务器,通过SIP协议,Web端使用jssip+webrtc和其他软电话进行通信

一、先配置FreeSWITCH(用的版本1.6.20)的配置:

1 、修改vars.xml文件,找到下面字段,并设置

1<X-PRE-PROCESS cmd="set" data="internal_ssl_enable=true"/> 2<X-PRE-PROCESS cmd="set" data="external_auth_calls=true"/> 3<X-PRE-PROCESS cmd="set" data="external_ssl_enable=true"/>

2、修改 autoload_configs/acl.conf.xml文件,增加acl选项

1 <list name="wan" default="allow"> 2 <node type="allow" cidr="10.10.21.0/22"/> 3 <node type="allow" cidr="10.250.250.0/24"/> 4 </list>

在配置文件 sip_profiles/internal.xml 增加如下配置

<param name="apply-candidate-acl" value="wan"/>

默认情况下建立连接失败,提示下面错误,并呼叫失败

1a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [WARNING] switch_core_media.c:3451 NO candidate ACL defined, Defaulting to wan.auto 2a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [DEBUG] switch_core_media.c:3481 Save audio Candidate cid: 1 proto: udp type: host addr: 10.10.21.32:52786 3a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [DEBUG] switch_core_media.c:3523 Searching for rtp candidate. 4a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [DEBUG] switch_core_media.c:3523 Searching for rtcp candidate. 5a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [DEBUG] switch_core_media.c:3567 sofia/internal/82s6ps5e@80ug9oo63ltj.invalid no suitable candidates found. 6a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [DEBUG] switch_core_media.c:4767 7a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [NOTICE] sofia.c:8240 Hangup sofia/internal/82s6ps5e@80ug9oo63ltj.invalid [CS_CONSUME_MEDIA] [INCOMPATIBLE_DESTINATION] 85fe89e1d-bb0c-473b-8877-d3648acd4076 2018-08-09 20:28:15.217384 [DEBUG] switch_core_codec.c:248 sofia/internal/1009@192.168.20.78 Restore previous codec PCMA:8. 9a21d347d-5622-451b-a1db-d241ca823e4d 2018-08-09 20:28:15.217384 [DEBUG] sofia.c:1453 Channel is already hungup.

在配置文件 sip_profiles/internal.xml 增加如下配置,解决这个问题

1<param name="apply-candidate-acl" value="localnet.auto"/> 2<param name="apply-candidate-acl" value="rfc1918.auto"/>

二、编写Web客户端

样式如下: 不是专业前端,没有做布局

启动之后,就和正常的SIP软终端一致了,通过FreSWITCH拨打其他软终端,测试正常。

源代码:基于JsSIP的客户端,参考网上,并自己修改并调试通过

1<!DOCTYPE html> 2<html> 3<head> 4 <title>JsSIP 对接 FreeSWITCH</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 6 <meta name="Author" content="wangweichao"/> 7 <meta name="description" content="JsSIP based example web application."/> 8 <script src="js/jssip-3.0.13.min.js" type="text/javascript"></script> 9 <style type="text/css"> 10 </style> 11</head> 12 13 14<body> 15<div id="login-page" 16 style="width: 424px; height: 260px; background-color: #f2f4f4; border: 1px solid grey; padding-top: 4px"> 17 <table border="0" frame="void" width="418px"> 18 <tr> 19 <td class="td_label" width="160px" align="right"><label for="sip_uri">SIP URI:</label></td> 20 <td width="258px"><input style="width:250px" id="sip_uri" type="text" value="sip:1009@192.168.20.78"/></td> 21 </tr> 22 <tr> 23 <td class="td_label" align="right"><label for="sip_password">SIP Password:</label></td> 24 <td><input style="width:250px" id="sip_password" type="password" value="654321"/></td> 25 </tr> 26 <tr> 27 <td class="td_label" align="right"><label for="ws_uri">WSS URI:</label></td> 28 <td><input style="width:250px" id="ws_uri" class="last unset" type="text" value="ws://192.168.20.78:5066"/> 29 </td> 30 </tr> 31 <tr> 32 <td class="td_label" align="right"><label class="input_label" for="sip_phone_number">SIP Phone Info:</label> 33 </td> 34 <td><input style="width:250px" id="sip_phone_number" type="text" value="1007"></td> 35 </tr> 36 <tr> 37 <td colspan="2" align="center"> 38 <button onclick="testStart()"> 初始化</button> 39 </td> 40 </tr> 41 42 <tr> 43 <td colspan="5" align="center"> 44 <button onclick="reg()"> 注册</button> 45 </td> 46 </tr> 47 48 <tr> 49 <td colspan="5" align="center"> 50 <button onclick="unReg()"> 注销</button> 51 </td> 52 </tr> 53 54 <tr> 55 <td colspan="2" align="center"> 56 <button onclick="testCall()"> 呼叫</button> 57 </td> 58 </tr> 59 60 <tr> 61 <td colspan="5" align="center"> 62 <button onclick="hangup()"> 挂断</button> 63 </td> 64 </tr> 65 </table> 66</div> 67 68<video id="videoView" width="420px" height="320px" autoplay></video> 69 70</body> 71<script type="text/javascript"> 72 var outgoingSession = null; 73 var incomingSession = null; 74 var currentSession = null; 75 var videoView = document.getElementById('videoView'); 76 77 var constraints = { 78 audio: true, 79 video: false, 80 mandatory: { 81 maxWidth: 640, 82 maxHeight: 360 83 } 84 }; 85 URL = window.URL || window.webkitURL; 86 87 var localStream = null; 88 var userAgent = null; 89 90 91 function testStart() { 92 93 var sip_uri_ = document.getElementById("sip_uri").value.toString(); 94 var sip_password_ = document.getElementById("sip_password").value.toString(); 95 var ws_uri_ = document.getElementById("ws_uri").value.toString(); 96 97 console.info("get input info: sip_uri = ", sip_uri_, " sip_password = ", sip_password_, " ws_uri = ", ws_uri_); 98 99 var socket = new JsSIP.WebSocketInterface(ws_uri_); 100 var configuration = { 101 sockets: [socket], 102 outbound_proxy_set: ws_uri_, 103 uri: sip_uri_, 104 password: sip_password_, 105 register: true, 106 session_timers: false 107 }; 108 109 userAgent = new JsSIP.UA(configuration); 110 111 //注册成功 112 userAgent.on('registered', function (data) { 113 console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase); 114 }); 115 116 //注册失败 117 userAgent.on('registrationFailed', function (data) { 118 console.log("registrationFailed, ", data); 119 //console.warn("registrationFailed, ", data.response.status_code, ",", data.response.reason_phrase, " cause - ", data.cause); 120 }); 121 122 //注册超时 123 userAgent.on('registrationExpiring', function () { 124 console.warn("registrationExpiring"); 125 }); 126 127 userAgent.on('newRTCSession', function (data) { 128 console.info('onNewRTCSession: ', data); 129 130 //通话呼入 131 if (data.originator == 'remote') { 132 console.info("incomingSession, answer the call----------------------"); 133 incomingSession = data.session; 134 data.session.answer({ 135 'mediaConstraints': { 136 'audio': true, 137 'video': false, 138 mandatory: {maxWidth: 640, maxHeight: 360} 139 }, 'mediaStream': localStream 140 }); 141 } else { 142 console.info("outgoingSession"); 143 outgoingSession = data.session; 144 outgoingSession.on('connecting', function (data) { 145 console.info('onConnecting - ', data.request); 146 currentSession = outgoingSession; 147 outgoingSession = null; 148 }); 149 } 150 data.session.on('accepted', function (data) { 151 console.info('onAccepted - ', data); 152 if (data.originator == 'remote' && currentSession == null) { 153 currentSession = incomingSession; 154 incomingSession = null; 155 console.info("setCurrentSession - ", currentSession); 156 } 157 }); 158 data.session.on('confirmed', function (data) { 159 console.info('onConfirmed - ', data); 160 if (data.originator == 'remote' && currentSession == null) { 161 currentSession = incomingSession; 162 incomingSession = null; 163 console.info("setCurrentSession - ", currentSession); 164 } 165 }); 166 data.session.on('sdp', function (data) { 167 console.info('onSDP, type - ', data.type, ' sdp - ', data.sdp); 168 }); 169 170 data.session.on('progress', function (data) { 171 console.info('onProgress - ', data.originator); 172 if (data.originator == 'remote') { 173 console.info('onProgress, response - ', data.response); 174 } 175 }); 176 data.session.on('peerconnection', function (data) { 177 console.info('onPeerconnection - ', data.peerconnection); 178 data.peerconnection.onaddstream = function (ev) { 179 console.info('onaddstream from remote ----------- ', ev); 180 videoView.src = URL.createObjectURL(ev.stream); 181 }; 182 }); 183 }); 184 185 userAgent.on('newMessage', function (data) { 186 if (data.originator == 'local') { 187 console.info('onNewMessage , OutgoingRequest - ', data.request); 188 } else { 189 console.info('onNewMessage , IncomingRequest - ', data.request); 190 } 191 }); 192 193 console.info("call register"); 194 195 userAgent.start(); 196 } 197 198 // Register callbacks to desired call events 199 var eventHandlers = { 200 'progress': function (e) { 201 console.log('call is in progress'); 202 }, 203 'failed': function (e) { 204 console.log('call failed: ', e); 205 }, 206 'ended': function (e) { 207 console.log('call ended : ', e); 208 }, 209 'confirmed': function (e) { 210 console.log('call confirmed'); 211 } 212 }; 213 214 function testCall() { 215 var sip_phone_number_ = document.getElementById("sip_phone_number").value.toString(); 216 217 var options = { 218 'eventHandlers': eventHandlers, 219 'mediaConstraints': { 220 'audio': true, 'video': false, 221 mandatory: {maxWidth: 640, maxHeight: 360} 222 }, 223 'mediaStream': localStream 224 }; 225 226 outgoingSession = userAgent.call(sip_phone_number_, options); 227 } 228 function reg() { 229 console.log('register----------->'); 230 userAgent.register(); 231 } 232 233 function unReg() { 234 console.log('unregister----------->'); 235 userAgent.unregister(true); 236 } 237 238 function hangup() { 239 console.log('hangup----------->'); 240 userAgent.terminateSessions(); 241 } 242 243</script> 244</html>
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )