1、建立连接
webrtc的连接就是一个webscoket,遵循的是tcp协议
在jssip中,jssip定义了一个JsSIP对象,其包含一个WebSocketInterface方法用来使用webscoket
WebSocketInterface(url)
- url:websocket连接地址
JsSIP.C.SESSION_EXPIRES=120 //websocket超时时间,默认值60
JsSIP.C.MIN_SESSION_EXPIRES=120 //websocket最小超时时间,默认值60
let url = '' //websocket地址(包含端口)
let socket = new JsSIP.WebSocketInterface('wss://' + url + '/ws')
scoket.via_transport = 'WS'
2、开启/注册
JsSIP.UA(option)
option参数
- sockets:创建的websocket连接,是一个数组
- uri:sip的注册地址,例如:sip:1001@example.com
- password:分机的注册密码
- register:是否开启自动注册,默认值是false,如果使用默认值或者指定了false,那么需要单独去掉用register()函数进行注册
以上三个参数的必填的参数,其他非必填参数请参考JsSIP官网文档:https://jssip.net/
let configuration = {
sockets: [ socket ],
uri: 'sip:'+sip+'@'+host+':'+port,
password : password,
authorization_user:sip,
display_name:sip,
register: true, //是否启用自动注册,默认值是false
registrar_server:'sip:'+ host,
session_timers: false,
pcConfig:{url:'stun:1.1.1.1:3478'},//示例地址,无效,请更换自己的stun服务器地址
user_agent:'jssip'
}
let sip_scoket = JsSIP.UA(configuration)
如果设置了register参数为true,同时会触发registered事件,如果设置为false,或者没有传递register参数,使用了默认值,那么就不会触发registered事件,需要等到调用了register()方法后才会触发registered事件
sip_scoket.on('registered',(data) => {
console.log('======注册完成======', data)
})
3、注册
register()
上面说的是通信的开启,如果设置了register参数为true,那么就会自动进行注册,不需要手动执行了,但是设置了false或者说没有传递register参数,那么默认会使用false,这时就需要手动进行注册了。
sip_scoket.register()
在执行该方法后会触发registered事件
sip_scoket.on('registered',(data) => {
console.log('======注册完成======', data)
})
4、呼叫
call(target, option)
-
target:呼叫的对象
-
option:其他额外的参数(这里主要说明一下mediaConstraints,这个是必须要传递的,不然会没有声音)
mediaConstraints是一个对象,包含2个参数,一个是audio,一个是video,表明指定当前通话是使用音频还是视频,也可以指定一个,也可以全部都指定,默认值为true,就是即使用音频也使用视频
sip_socket.call(
'1001',
mediaConstraints:{audio:true}
)
呼叫成功后会触发newRTCSession事件,需要在这里进行音频流的处理(我这里以音频流为例),newRTCSession事件的返回值中有一个originator参数,如果值为remote那么表明这是一个呼入,如果是local那么表明这是一个外呼,呼入和外呼对于音频流的处理 位置也是不一样的,如果是外呼直接在newRTCSession的返回值的
sip_socket.on("newRTCSession", (e) => {
console.log("===========newRTCSession==========", e)
session = e.session
if(e.originator == 'remote'){
session.on("peerconnection", (data) => {
addTrack(data,'incomming')
})
} else {
addTrack(e.session._connection,'outcomming')
}
}
//添加音频流函数
function addTrack(data, type) {
console.log("========addTrack==============")
if (type == "incomming") {
data.peerconnection.ontrack = () => {
let remoteStream = new MediaStream();
let receivers = session._connection.getReceivers();
receivers.forEach((recevier) => {
if (recevier.track.kind == "audio") {
remoteStream.addTrack(recevier.track);
document.getElementById("remoteAudio").srcObject = remoteStream;
}
});
};
} else {
data.ontrack = () => {
let remoteStream = new MediaStream()
let receivers = session._connection.getReceivers()
receivers.forEach((recevier) => {
if (recevier.track.kind == "audio") {
remoteStream.addTrack(recevier.track)
document.getElementById("remoteAudio").srcObject = remoteStream
}
})
}
}
}
5、挂断
terminate()
挂断调用terminate()方法,挂断后会触发ended事件。在ended事件中,可以通过返回值的originator获得是本地挂断还是被叫挂断,如果originator的值为local那么就是本地挂断或者叫主叫挂断,如果originator的值为remote,那么就是被叫挂断。同时,返回值的cause会返回挂断的原因。
session.terminate()
session.on('ended', (data) => {
if(data.originator == 'local') {
console.log('主叫挂断')
}
if(data.originator == 'remote') {
console.log('被叫挂断')
}
})
6、接听
answer(option)
option的参数主要说明一下mediaConstraints
mediaConstraints是一个对象,包含2个参数,一个是audio,一个是video,表明指定当前通话是使用音频还是视频,也可以指定一个,也可以全部都指定,默认值为true,就是及使用音频也使用视频
session.answer({
mediaConstraints: { audio: true }
})
接听完成后会触发accepted事件,可以根据事件返回值的originator参数来获得是主叫接听还是被叫接听,如果值为remote那么就是被叫接听,如果是local那么就是主叫接听。
session.on('accepted', (data) => {
if(data.originator == 'remote') {
consloe.log('被叫接听')
}
if(data.originator == 'local') {
consloe.log('主叫接听')
}
})
7、注销
注销实际上就是直接关闭当前连接就可以了,使用stop()方法
sip_scoket.stop()
注销后会触发unregistered事件,整个注销过程为固定的2秒钟,如果在注销后又其他逻辑运行,建议2秒钟后再执行其他逻辑。
sip_socket.on('unregistered', (e) => {
consloe.log('======注销======', e)
})
以上内容是JsSIP的基本使用,后续会逐渐的汇总每一个步骤所涉及到的具体细节性的内容。