/* Real incremental website WebSocket; never resubmit a question automatically. */ (function(root){ function request(url,payload,onSnapshot){ return new Promise((resolve,reject)=>{ const target=new URL(url+'/stream',location.href); if(target.origin!==location.origin){reject(new Error('对话地址无效'));return} target.protocol=target.protocol==='https:'?'wss:':'ws:'; let socket,settled=false,ready=false,sent=false; const timer=setTimeout(()=>finish(new Error('回复连接超时,尚未确认完整回答;请重试原问题。')),125000); const leave=()=>finish(new Error('连接已断开,可重试原问题查询同一次请求。')); const invalid=()=>new Error('回复连接中断,尚未确认完整回答;请重试原问题。'); function finish(error,data){ if(settled)return;settled=true;clearTimeout(timer);root.removeEventListener('pagehide',leave); if(socket&&(socket.readyState===WebSocket.OPEN||socket.readyState===WebSocket.CONNECTING))socket.close(); if(error)reject(error);else resolve(data); } root.addEventListener('pagehide',leave,{once:true}); try{socket=new WebSocket(target.href)}catch{finish(invalid());return} socket.addEventListener('open',()=>{ if(settled||sent)return; sent=true;socket.send(JSON.stringify(payload)); }); socket.addEventListener('message',event=>{ if(settled)return; try{ if(typeof event.data!=='string'||event.data.length>262144)throw invalid(); const frame=JSON.parse(event.data),data=frame.data; if(frame.event==='ready'){ if(data?.v!==1||ready)throw invalid();ready=true; }else if(frame.event==='ping'){ if(!ready)throw invalid(); }else if(frame.event==='snapshot'){ if(!ready||typeof data?.text!=='string'||data.text.length>65536)throw invalid(); onSnapshot(data.text); }else if(frame.event==='completed'){ if(!ready||typeof data?.answer!=='string'||typeof data.mode!=='string')throw invalid(); finish(null,data); }else throw invalid(); }catch{finish(invalid())} }); socket.addEventListener('error',()=>finish(invalid())); socket.addEventListener('close',()=>{if(!settled)finish(invalid())}); }); } root.ZhiweiChatStream={request}; })(window);