Reactjs twilio设备连接和重新连接
我正在尝试为twilio调用连接创建上下文api。如果我做得正确与否,我想从twilio专家那里得到帮助。在这种情况下,我试图做的是连接twilio设备,如果令牌过期,则重新连接。但是通过这种方式,呼出的电话还没有工作,我可以看到设备已经准备好打印在我的控制台上。当我尝试调用时,Reactjs twilio设备连接和重新连接,reactjs,twilio,Reactjs,Twilio,我正在尝试为twilio调用连接创建上下文api。如果我做得正确与否,我想从twilio专家那里得到帮助。在这种情况下,我试图做的是连接twilio设备,如果令牌过期,则重新连接。但是通过这种方式,呼出的电话还没有工作,我可以看到设备已经准备好打印在我的控制台上。当我尝试调用时,deviceInstance状态显示为空 我就是这样做的 import { Device, Connection } from 'twilio-client'; import twilioReducers from '
deviceInstance
状态显示为空
我就是这样做的
import { Device, Connection } from 'twilio-client';
import twilioReducers from './twilioReducers';
interface ITwilioContext {
// device?: Device;
setDeviceOnline?: () => void;
state: InitialStateType;
dispatch: React.Dispatch<any>;
handleDeviceOutgoing: (params: OutgoingProps) => void;
}
export const TwilioContext = createContext<ITwilioContext>({});
const TwilioProvider = ({ children }: { children: React.ReactNode }) => {
const [deviceInstance, setDeviceInstance] = useState<Device | null>(null);
const [activeWorkspaceId] = useLocalStorage('activeWorkspaceId', null);
const { t } = useTranslation();
const [getVoiceToken, { data }] = useLazyQuery(VOICE_TOKEN, {
fetchPolicy: 'network-only',
errorPolicy: 'ignore',
onError: err => console.error(err),
});
// Commented inorder to prevent reintialization
// const device = new Device();
const initialState = { direction: '', showPhoneWidget: false };
const [state, dispatch] = useReducer(twilioReducers, initialState);
/* event handlers for twilio device */
const handleDeviceReady = (device: Device) => {
console.log('Device ready');
setDeviceInstance(device);
};
const handleDeviceOffline = async (device: Device) => {
console.log('Device offline', device);
if (device.token) {
const twilioTokenDecoded = jwtDecode<JwtPayload>(device.token);
if ((twilioTokenDecoded as any).exp <= Date.now() / 1000) {
await getVoiceToken({});
console.log('twilio new token data', data);
}
}
};
const handleDeviceError = (error: Connection.Error) => {
console.log('Device error', error);
if (TWILIO_ERRORS[error.code] !== undefined) {
ToastMessage({
content: t(TWILIO_ERRORS[error.code].errorKey, TWILIO_ERRORS[error.code].message),
type: 'danger',
});
}
};
/* ----------------------------- */
/* handle incoming calls */
const handleDeviceIncoming = (connection: Connection) => {
console.log('incoming', connection);
dispatch({
type: ACTIONS.INCOMING_CALL,
data: connection,
});
connection.on(deviceEvent.CANCEL, () => {
console.log('incoming-cancel');
dispatch({
type: ACTIONS.INCOMING_CALL_CANCEL,
});
});
connection.on(deviceEvent.DISCONNECT, () => {
console.log('incoming-disconnect');
dispatch({
type: ACTIONS.INCOMING_CALL_DISCONNECT,
});
});
connection.on(deviceEvent.ACCEPT, () => {
console.log('incoming-call-accept');
dispatch({
type: ACTIONS.ANSWER_INCOMING_CALL,
});
});
connection.on(deviceEvent.REJECT, () => {
console.log('incoming-call-reject');
dispatch({
type: ACTIONS.REJECT_INCOMING_CALL,
updateConversationStatus: true,
});
});
connection.on(deviceEvent.ERROR, (err: Connection.Error) => {
console.log('Connection error occured', err);
dispatch({
type: ACTIONS.INCOMING_CALL_ERROR,
status: 'error',
});
});
};
/* ----------------------------- */
/* handle outgoing calls */
const handleDeviceOutgoing = (params: OutgoingProps) => {
if (deviceInstance) {
if (deviceInstance.isInitialized || deviceInstance.status() !== 'ready') {
ToastMessage({ content: t('error.deviceSetup', 'Device is offline.'), type: 'danger' });
return;
}
const connection = deviceInstance.connect(params); // copied from premvp
dispatch({
type: ACTIONS.OUTGOING_CALL_INITIATED,
data: connection,
status: 'connecting',
channelId: params?.channel_sid,
});
connection.on(deviceEvent.RINGING, (val: boolean) => {
if (val) {
dispatch({
type: ACTIONS.OUTGOING_CALL_RINGING,
});
}
});
connection.on(deviceEvent.CANCEL, () => {
console.log('Connection cancelled');
dispatch({
type: ACTIONS.OUTGOING_CALL_DISCONNECT,
});
});
connection.on(deviceEvent.DISCONNECT, (conn: Connection) => {
// handle user hungup
console.log('Connection disconnected', conn);
dispatch({
type: ACTIONS.OUTGOING_CALL_DISCONNECT,
});
});
connection.on(deviceEvent.ACCEPT, (conn: Connection) => {
console.log('Connected to the user', conn); // handle user answercall
dispatch({
type: ACTIONS.OUTGOING_CALL_ANSWERED,
});
});
connection.on(deviceEvent.REJECT, (conn: Connection) => {
console.log('Rejected', conn); // handle user answercall
dispatch({
type: ACTIONS.REJECT_OUTGOING_CALL,
});
});
connection.on(deviceEvent.ERROR, (err: Connection.Error) => {
console.log('Connection error occured', err);
});
} else {
console.log('No Device Instance exist');
}
};
/* ----------------------------- */
useEffect(() => {
const device = new Device();
console.log('device', device, data);
if (data?.getVoiceToken?.data?.voiceToken) {
device.setup(data?.getVoiceToken?.data?.voiceToken, deviceConfig);
device.on(deviceEvent.READY, handleDeviceReady);
device.on(deviceEvent.OFFLINE, handleDeviceOffline);
device.on(deviceEvent.ERROR, handleDeviceError);
device.on(deviceEvent.INCOMING, handleDeviceIncoming);
}
return () => {
device.destroy();
setDeviceInstance(null);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data?.getVoiceToken?.data?.voiceToken]);
useEffect(() => {
if (activeWorkspaceId !== '') {
getVoiceToken({});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeWorkspaceId]);
const value = useMemo(() => {
return {
state,
dispatch,
deviceInstance,
handleDeviceOutgoing,
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state]);
return <TwilioContext.Provider value={value}>{children}</TwilioContext.Provider>;
};
export default TwilioProvider;
从“twilio客户端”导入{Device,Connection};
从“/TwilioEducers”导入TwilioEducers;
接口ITwilioContext{
//设备?:设备;
setDeviceOnline?:()=>void;
状态:InitialStateType;
调度:反应,调度;
handleDeviceOutgoing:(参数:OutgoingProps)=>void;
}
export const TwilioContext=createContext({});
const TwilioProvider=({children}:{children:React.ReactNode})=>{
常量[deviceInstance,setDeviceInstance]=useState(null);
const[activeWorkspaceId]=useLocalStorage('activeWorkspaceId',null);
const{t}=useTranslation();
const[getVoiceToken,{data}]=useLazyQuery(VOICE_TOKEN{
fetchPolicy:“仅限网络”,
errorPolicy:“忽略”,
onError:err=>console.error(err),
});
//注释以防止重新激活
//const device=新设备();
const initialState={direction:'',showPhoneWidget:false};
const[state,dispatch]=useReducer(twilioReducers,initialState);
/*twilio设备的事件处理程序*/
const handledevicerady=(设备:设备)=>{
console.log(“设备就绪”);
设置设备状态(设备);
};
const handleDeviceOffline=异步(设备:设备)=>{
console.log(“设备脱机”,设备);
if(设备令牌){
const TwilioTokendecode=jwtDecode(device.token);
如果((如有)。exp{
console.log('设备错误',错误);
if(TWILIO_错误[error.code]!==未定义){
演讲信息({
内容:t(TWILIO_错误[error.code].errorKey,TWILIO_错误[error.code].message),
类型:“危险”,
});
}
};
/* ----------------------------- */
/*接听来电*/
const handleDeviceIncoming=(连接:连接)=>{
console.log('传入',连接);
派遣({
类型:ACTIONS.INCOMING_CALL,
数据:连接,
});
connection.on(deviceEvent.CANCEL,()=>{
console.log('incoming-cancel');
派遣({
类型:ACTIONS.INCOMING\u CALL\u CANCEL,
});
});
connection.on(deviceEvent.DISCONNECT,()=>{
console.log('incoming-disconnect');
派遣({
类型:ACTIONS.INCOMING\u CALL\u DISCONNECT,
});
});
connection.on(deviceEvent.ACCEPT,()=>{
console.log('incoming-call-accept');
派遣({
类型:ACTIONS.ANSWER\u传入\u呼叫,
});
});
connection.on(deviceEvent.REJECT,()=>{
console.log(“传入呼叫-拒绝”);
派遣({
类型:ACTIONS.REJECT_传入_呼叫,
updateConversationStatus:true,
});
});
connection.on(deviceEvent.ERROR,(err:connection.ERROR)=>{
console.log('发生连接错误',err);
派遣({
类型:ACTIONS.INCOMING\u CALL\u ERROR,
状态:“错误”,
});
});
};
/* ----------------------------- */
/*处理外线电话*/
const handledeviceoutgo=(参数:OutgoingProps)=>{
if(设备持续时间){
if(deviceInstance.isInitialized | | deviceInstance.status()!='ready'){
ToastMessage({content:t('error.deviceSetup','Device is offline',键入'danger'});
返回;
}
const connection=deviceInstance.connect(params);//从premvp复制
派遣({
类型:ACTIONS.Outing_CALL_INITIATED,
数据:连接,
状态:“正在连接”,
channelId:params?.channel_sid,
});
connection.on(deviceEvent.RINGING)(val:boolean)=>{
if(val){
派遣({
类型:ACTIONS.outing\u CALL\u RINGING,
});
}
});
connection.on(deviceEvent.CANCEL,()=>{
console.log(“连接已取消”);
派遣({
类型:ACTIONS.outing\u CALL\u DISCONNECT,
});
});
connection.on(deviceEvent.DISCONNECT)(连接:连接)=>{
//处理用户hungup
console.log(“连接断开”,连接);
派遣({
类型:ACTIONS.outing\u CALL\u DISCONNECT,
});
});
connection.on(deviceEvent.ACCEPT,(conn:connection)=>{
console.log('Connected to the user',conn);//处理用户应答呼叫
派遣({
类型:ACTIONS.outing\u CALL\u responsed,
});
});
connection.on(deviceEvent.REJECT)(连接:连接)=>{
console.log('Rejected',conn);//处理用户应答呼叫
派遣({
类型:ACTIONS.REJECT_传出_呼叫,
});
});
connection.on(deviceEvent.ERROR,(err:connection.ERROR)=>{
console.log('发生连接错误',err);
});
}否则{
log('不存在设备实例');
}
};
/* ----------------------------- */
useffect(()=>{
const device=新设备();
console.log('设备'、设备、数据);
if(数据?.getVoiceToken?.data?.voiceToken){
设备设置(数据?.getVoiceToken?.data?.voiceToken,设备配置);
设备打开(deviceEvent.READY,handleDeviceReady);
device.on(deviceEvent.OFFLINE,handleDeviceOffline);
device.on(deviceEvent.ERROR,handleDeviceError);
设备上(deviceEvent.INCOMING,handleDeviceIncoming);
}
return()=>{
destroy();
setDeviceInstance(空);
};
//eslint禁用下一行react HOOK/deps
},[data?.getVoiceToken?.data?.voiceToken]);
useffect(()=>{
如果(activeWorkspaceId!=''){
getVoiceToken({});
}
//eslint禁用下一行反应挂钩/排气