class DataHubClient {
constructor(serverUrl) {
this.serverUrl = serverUrl;
this.componentMap = new Map();
this.ws = null;
this.reconnectAttempts = 0;
this.maxReconnect = 3;
this.connect();
}
static genKey(component) {
return `${component.id}_${component.fetchDataConfig.url}_${JSON.stringify(component.fetchDataConfig.params)}_${component.frequency}`;
}
registerComponent(component) {
const key = DataHubClient.genKey(component);
this.componentMap.set(key, {
component,
fetchDataConfig: component.fetchDataConfig,
frequency: component.frequency,
});
this.sendRegister(key, component);
}
sendRegister(key, component) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({
type: "REGISTER",
data: {
key,
componentId: component.id,
fetchConfig: component.fetchDataConfig,
frequency: component.frequency,
}
}));
}
}
connect() {
this.ws = new WebSocket(this.serverUrl);
this.ws.onopen = () => {
this.reconnectAttempts = 0;
for (const [key, { component }] of this.componentMap.entries()) {
this.sendRegister(key, component);
}
};
this.ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "DATA_UPDATE") {
const { key, newData } = msg;
const info = this.componentMap.get(key);
if (info) {
info.component.onDataUpdated(newData);
}
}
};
this.ws.onclose = () => {
if (this.reconnectAttempts < this.maxReconnect) {
setTimeout(() => {
this.reconnectAttempts++;
this.connect();
}, 5000);
}
};
}
}
const client = new DataHubClient("ws://localhost:8080/hub");
client.registerComponent({
id: "weather-widget",
fetchDataConfig: {
url: "https://api.weather.com/current",
method: "GET",
params: { city: "beijing" }
},
frequency: "low",
onDataUpdated: (data) => {
console.log("天气数据更新:", data);
}
});
console