no message

This commit is contained in:
kuaifan 2023-07-28 21:24:29 +08:00
parent a8481e0ad5
commit 479e9f83a9
3 changed files with 118 additions and 21 deletions

View File

@ -1277,6 +1277,9 @@
.child-view { .child-view {
background-color: #fff; background-color: #fff;
} }
.page-login {
background-color: #f8f8f8;
}
${this.utils.addExtraStyle()} ${this.utils.addExtraStyle()}
} }

View File

@ -1,7 +1,7 @@
import {Store} from 'le5le-store'; import {Store} from 'le5le-store';
import * as openpgp from 'openpgp_hi/lightweight'; import * as openpgp from 'openpgp_hi/lightweight';
import {languageType} from "../language"; import {languageType} from "../language";
import {$callData, $urlSafe} from './utils' import {$callData, $urlSafe, SSEClient} from './utils'
export default { export default {
/** /**
@ -2850,27 +2850,36 @@ export default {
* @param streamUrl * @param streamUrl
*/ */
streamDialogMsg({state, dispatch}, streamUrl) { streamDialogMsg({state, dispatch}, streamUrl) {
const sse = new EventSource(streamUrl) if (!/^https*:\/\//i.test(streamUrl)) {
sse.addEventListener("append", e => { streamUrl = $A.apiUrl(`..${streamUrl}`)
}
const sse = new SSEClient(streamUrl)
sse.subscribe(['append', 'replace', 'done'], (type, e) => {
switch (type) {
case 'append':
Store.set('dialogMsgChange', { Store.set('dialogMsgChange', {
id: e.lastEventId, id: e.lastEventId,
type: 'append', type: 'append',
text: e.data text: e.data
}); });
}) break;
sse.addEventListener("replace", e => {
case 'replace':
Store.set('dialogMsgChange', { Store.set('dialogMsgChange', {
id: e.lastEventId, id: e.lastEventId,
type: 'replace', type: 'replace',
text: e.data text: e.data
}); });
}) break;
sse.addEventListener("done", _ => {
case 'done':
const index = state.dialogSseList.findIndex(item => sse === item.sse) const index = state.dialogSseList.findIndex(item => sse === item.sse)
if (index > -1) { if (index > -1) {
state.dialogSseList.splice(index, 1) state.dialogSseList.splice(index, 1)
} }
sse.close() sse.unsunscribe()
break;
}
}) })
state.dialogSseList.push({sse, time: $A.Time()}) state.dialogSseList.push({sse, time: $A.Time()})
if (state.dialogSseList.length > 10) { if (state.dialogSseList.length > 10) {

View File

@ -84,3 +84,88 @@ export function $urlSafe(value, encode = true) {
} }
return value return value
} }
const SSEDefaultOptions = {
retry: 5,
interval: 3 * 1000,
};
/**
* EventSource
*/
export class SSEClient {
constructor(url, options = SSEDefaultOptions) {
this.url = url;
this.es = null;
this.options = options;
this.retry = options.retry;
this.timer = null;
}
_onOpen() {
if (window.systemInfo.debug === "yes") {
console.log("SSE open: " + this.url);
}
}
_onMessage(type, handler) {
return (event) => {
this.retry = this.options.retry;
if (typeof handler === "function") {
handler(type, event);
}
};
}
_onError(type, handler) {
return () => {
if (window.systemInfo.debug === "yes") {
console.log("SSE retry: " + this.url);
}
if (this.es) {
this._removeAllEvent(type, handler);
this.unsunscribe();
}
if (this.retry > 0) {
this.timer = setTimeout(() => {
this.subscribe(type, handler);
}, this.options.interval);
} else {
this.retry--;
}
};
}
_removeAllEvent(type, handler) {
type = $A.isArray(type) ? type : [type]
this.es.removeEventListener("open", this._onOpen);
type.some(item => {
this.es.removeEventListener(item, this._onMessage(item, handler));
})
this.es.removeEventListener("error", this._onError(type, handler));
}
subscribe(type, handler) {
type = $A.isArray(type) ? type : [type]
this.es = new EventSource(this.url);
this.es.addEventListener("open", this._onOpen);
type.some(item => {
this.es.addEventListener(item, this._onMessage(item, handler));
})
this.es.addEventListener("error", this._onError(type, handler));
}
unsunscribe() {
if (this.es) {
this.es.close();
this.es = null;
}
if (this.timer) {
clearTimeout(this.timer);
}
if (window.systemInfo.debug === "yes") {
console.log("SSE cancel: " + this.url);
}
}
}