Created
October 24, 2018 14:42
-
-
Save poberwong/6134c6728035902971ec6588d5fa0303 to your computer and use it in GitHub Desktop.
IM 新升级内容
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { observable, action } from 'mobx' | |
import config from 'app/config' | |
import { message } from 'antd' | |
import NIM from 'app/utils/NIM_Web_NIM_v5.2.1.js' | |
import WebRTC from 'app/utils/NIM_Web_WebRTC_v5.2.1.js' | |
import globalStore, { PLAY_TYPE } from 'app/stores/global' | |
import { getToken } from 'app/utils/localTools' | |
import { computed } from 'mobx' | |
const FREE = 'free' | |
const WAITING = 'waiting' | |
const CALLING = 'busy' | |
const BECALLED = 'receive call' | |
export const STATUS = { | |
free: FREE, | |
waiting: WAITING, | |
calling: CALLING, | |
beCalled: BECALLED | |
} | |
const TYPE_VIDEO = 'video' | |
const TYPE_AUDIO = 'audio' | |
const typeMap = new Map([ | |
[WebRTC.NETCALL_TYPE_VIDEO, TYPE_VIDEO], | |
[WebRTC.NETCALL_TYPE_AUDIO, TYPE_AUDIO], | |
]) | |
class CommunicateStore { | |
medicalRecordStore | |
amIChatting = false // 该量只应用于话单的发送功能模块上,不会对其他模块产生影响 | |
globalStore | |
@observable accid = '' | |
@observable targetAccid = '' | |
@observable status = FREE | |
@observable ready = false | |
@observable duration = [0, 0] | |
@observable sessionConfig = { | |
recordVideo: true, | |
recordAudio: true, | |
videoQuality: WebRTC.CHAT_VIDEO_QUALITY_480P, | |
} | |
@observable videoMini = false | |
@observable visible = false | |
@observable callType = '' | |
@observable chatStore | |
constructor () { | |
NIM.use(WebRTC) | |
} | |
setIamChatting = (amIChatting) => { | |
this.amIChatting = amIChatting | |
} | |
@computed get avatar() { | |
if (this.chatStore && this.chatStore.membersInfoCache.get(this.targetAccid)) { | |
return this.chatStore.membersInfoCache.get(this.targetAccid).avatar | |
} else { | |
return null | |
} | |
} | |
@action maxVideoView = () => { | |
console.log('放大了') | |
this.videoMini = false | |
} | |
@action minVideoView = () => { | |
this.videoMini = true | |
} | |
@action hidden = () => { | |
this.visible = false | |
} | |
@action show = () => { | |
this.visible = true | |
} | |
@action setSessionConfig = (obj) => { | |
this.sessionConfig = {...this.sessionConfig, ...obj} | |
} | |
@action setNim = () => { | |
const { firstAccid } = this.chatStore | |
this.nim = this.chatStore[firstAccid].nim | |
} | |
@action setStatus = (status) => { | |
this.status = status | |
} | |
@action listenEvent = () => { | |
// this.netcall.on('beCalling', obj => { | |
// const { channelId } = obj | |
// console.log('正在被呼叫...') | |
// | |
// if (!this.netcall.calling && !this.beCalling) { | |
// this.beCalling = true | |
// this.beCalledInfo = obj | |
// globalStore.play(PLAY_TYPE.RING) | |
// this.setStatus(BECALLED) | |
// } else { | |
// console.log('我在通话中,拒绝通话外的人') | |
// this.netcall.control({ | |
// channelId: channelId, | |
// command: WebRTC.NETCALL_CONTROL_COMMAND_BUSY | |
// }) | |
// } | |
// }) | |
this.netcall.on('callAccepted', obj => { | |
console.log('接听成功') | |
globalStore.pause('ringMp3') | |
this.setStatus(CALLING) | |
clearTimeout(this.overtimetimer) | |
this.startTimer() | |
this.netcall.startRtc().then(() => { | |
this.startDeviceVideo() | |
.then(() => { | |
// 开启本地视频预览 | |
this.netcall.startLocalStream(document.getElementById('local')) | |
}) | |
.catch(err => console.log('启动摄像头失败', err)) | |
.then(() => this.startDeviceAudioIn()) | |
}).catch((err) => { | |
console.log('发生错误, 挂断通话') | |
console.log(err) | |
this.hangup() | |
}) | |
}) | |
// 在回调里监听对方加入通话,并显示对方的视频画面 | |
this.netcall.on('remoteTrack', (obj) => { | |
console.log('user join', obj) | |
// 播放对方声音 | |
this.netcall.startDevice({ | |
type: WebRTC.DEVICE_TYPE_AUDIO_OUT_CHAT | |
}).catch((err) => { | |
console.log('播放对方的声音失败') | |
console.error(err) | |
}) | |
// 预览对方视频画面 | |
this.netcall.startRemoteStream({ | |
account: obj.account, | |
node: document.getElementById('remote') | |
}) | |
this.netcall.setVideoViewRemoteSize({ | |
width: 500, | |
height: 500, | |
cut: true | |
}) | |
}) | |
this.netcall.on('callRejected', obj => { // TODO, 抽象 | |
console.log('被拒绝了') | |
this.resetAll() | |
}) | |
this.netcall.on('hangup', obj => { | |
console.log('obj', obj) | |
console.log('被挂断了1') | |
globalStore.pause('ringMp3') | |
this.resetAll() | |
}) | |
// this.netcall.on('control', obj => { | |
// console.log('obj', obj) | |
// switch(obj.type) { | |
// case WebRTC.NETCALL_CONTROL_COMMAND_SWITCH_AUDIO_TO_VIDEO: | |
// console.log('video: ') | |
// | |
// this.type = TYPE_VIDEO | |
// this.openVideo() | |
// break | |
// case WebRTC.NETCALL_CONTROL_COMMAND_SWITCH_VIDEO_TO_AUDIO: | |
// console.log('audio') | |
// this.type = TYPE_AUDIO | |
// this.closeVideo() | |
// break | |
// case WebRTC.NETCALL_CONTROL_COMMAND_BUSY: | |
// console.log('占线') | |
// // this.disposeMultiLogin() | |
// break | |
// default: console.log('other command') | |
// } | |
// }) | |
} | |
@action init = () => { | |
this.netcall = WebRTC.getInstance({ | |
nim: this.nim, | |
container: document.getElementById('local'), | |
remoteContainer: document.getElementById('remote'), | |
debug: true, | |
}) | |
this.ready = true | |
} | |
switchType = (type) => { | |
this.type = type | |
if (type === TYPE_VIDEO) { | |
this.switchAudioToVideo() | |
} else { | |
this.switchVideoToAudio() | |
} | |
} | |
switchAudioToVideo = () => { | |
this.netcall.control({ | |
command: WebRTC.NETCALL_CONTROL_COMMAND_SWITCH_AUDIO_TO_VIDEO | |
}) | |
this.openVideo() | |
} | |
switchVideoToAudio = () => { | |
this.netcall.control({ | |
command: WebRTC.NETCALL_CONTROL_COMMAND_SWITCH_VIDEO_TO_AUDIO | |
}) | |
this.closeVideo() | |
} | |
openVideo = () => { | |
this.startDeviceVideo() | |
.then(() => this.netcall.startLocalStream()) | |
.then(() => this.netcall.switchAudioToVideo()) | |
.then(() => this.netcall.startRemoteStream()) | |
.catch(err => message.error(err)) | |
} | |
closeVideo = () => { | |
this.netcall.stopLocalStream() | |
this.netcall.stopRemoteStream() | |
this.netcall.switchVideoToAudio() | |
} | |
startTimer = () => { | |
this.resetTimer() | |
this.timer = setInterval(() => { | |
const [mins, seconds] = this.duration | |
if (seconds + 1 === 60) { | |
this.duration = [ | |
mins + 1, | |
0 | |
] | |
} else { | |
this.duration = [ | |
mins, | |
seconds + 1 | |
] | |
} | |
}, 1000) | |
} | |
resetTimer = () => { | |
if(this.timer) { | |
clearTimeout(this.timer) | |
this.timer = null | |
} | |
this.duration = [0, 0] | |
} | |
@action setUserData = (userData) => { | |
this.userData = userData | |
this.accid = userData.doctorAccid | |
this.targetAccid = userData.accid | |
this.tid = userData.tid | |
} | |
@action setCallType = (type) => { | |
this.callType = +type | |
} | |
@action loadAvatar = () => { | |
this.chatStore.updateCache({from: this.targetAccid}) | |
} | |
@action connectWebsocket = (type) => { | |
if(!this.websocket) { | |
this.websocket = new WebSocket(`${config.wsUri}/chats/${this.accid}?jwt=${getToken()}`) | |
} | |
this.websocket.onmessage = (msg) => { | |
const isCalling = JSON.parse(msg.data).calling | |
if (!isCalling) { | |
if (this.avatar === null) { | |
this.loadAvatar() | |
} | |
this.setCallType(type) | |
if (!this.ready) { | |
this.setNim() | |
this.init() | |
this.listenEvent() | |
} | |
this.setIamChatting(true) | |
this.startChatting() | |
} else { | |
alert('当前账号正在通话') | |
} | |
} | |
} | |
@action closeConnection = () => { | |
console.log('close ws connection') | |
if(this.websocket) { | |
this.websocket.close() | |
this.websocket = null | |
} | |
} | |
resetAll = () => { | |
this.resetTimer() | |
clearTimeout(this.overtimetimer) | |
setTimeout(() => { // 不论是否收到通知话单,使用定时器强制恢复状态(避免因为云信服务器未发出的原因无法恢复状态,允许重复恢复) | |
this.setIamChatting(false) | |
}, 1500) | |
this.setStatus(FREE) | |
this.beCalling = false | |
this.beCalledInfo = null | |
globalStore.pause('ringMp3') | |
this.closeConnection() | |
if (this.medicalRecordStore) { // 写到 | |
this.hidden() | |
} | |
} | |
@action startChatting = (type) => { | |
this.setStatus(WAITING) | |
this.netcall.call({ | |
type: this.callType, | |
account: this.chatStore.targetAccid, | |
pushConfig: { | |
pushContent: `护士正邀请您进行${type === WebRTC.NETCALL_TYPE_VIDEO ? '视频' : '语音'}问诊`, | |
custom: JSON.stringify({ | |
key: 'value' | |
}), | |
pushPayload: JSON.stringify({ | |
type: typeMap[this.callType] | |
}), | |
sound: 'video_chat_tip_sender.aac' | |
}, | |
webrtcEnable: true, | |
sessionConfig: this.sessionConfig | |
}) | |
.then( | |
res => { // reject: 对方无人接听; | |
globalStore.play(PLAY_TYPE.RING) | |
if (this.medicalRecordStore) { | |
this.show() | |
} | |
this.overtimetimer = setTimeout(() => { // 对方未响应60秒超时 | |
if (!this.netcall.callAccepted) { | |
this.hangup() | |
globalStore.play(PLAY_TYPE.NO_RESPONSE) // 播放:对方无人接听音频 | |
this.setStatus(FREE) | |
console.log('对方无人接听') | |
} | |
}, 60000) // 60 秒超时 | |
}, | |
err => { // reject: 对方不在线; | |
if (err.event.code === 11001) { | |
globalStore.play(PLAY_TYPE.OFFLINE) | |
} else { | |
message.error('通话不可达:' + err.event.code) | |
} | |
this.hangup() | |
} | |
) | |
} | |
hangup = () => { // 主叫方挂断 | |
console.log('我是主叫方 我挂断了') | |
this.netcall.hangup() | |
this.resetAll() | |
return Promise.resolve() | |
} | |
rejectCall = () => { // 被叫方拒绝接听 | |
console.log('我是被叫方 我挂断了') | |
this.netcall.control({ | |
channelId: this.beCalledInfo.channelId, | |
command: WebRTC.NETCALL_CONTROL_COMMAND_BUSY | |
}) | |
this.netcall.response({ | |
accepted: false, | |
beCalledInfo: this.beCalledInfo | |
}) | |
this.resetAll() | |
} | |
startDeviceAudioIn = () => { | |
return this.netcall.startDevice({ | |
type: WebRTC.DEVICE_TYPE_AUDIO_IN | |
}).then(() => { | |
// 通知对方自己开启了麦克风 | |
this.netcall.control({ | |
command: WebRTC.NETCALL_CONTROL_COMMAND_NOTIFY_AUDIO_ON | |
}) | |
// 设置采集音量 | |
this.netcall.setCaptureVolume(255) | |
}).catch(() => { | |
console.log('启动麦克风失败') | |
}) | |
} | |
startDeviceVideo = () => { | |
return this.netcall.startDevice({ | |
type: WebRTC.DEVICE_TYPE_VIDEO | |
}).then(() => { | |
// 通知对方自己开启了摄像头 | |
this.netcall.control({ | |
command: WebRTC.NETCALL_CONTROL_COMMAND_NOTIFY_VIDEO_ON | |
}) | |
}).catch(() => { | |
// 通知对方自己的摄像头不可用 | |
this.netcall.control({ | |
command: WebRTC.NETCALL_CONTROL_COMMAND_SELF_CAMERA_INVALID | |
}) | |
console.log('启动摄像头失败') | |
}) | |
} | |
} | |
export default new CommunicateStore() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment