Update server.js
Browse files
server.js
CHANGED
|
@@ -61,25 +61,25 @@ class SpaceCache {
|
|
| 61 |
}
|
| 62 |
|
| 63 |
invalidate() {
|
| 64 |
-
this.lastUpdate =
|
| 65 |
-
console.log('缓存被强制失效');
|
| 66 |
}
|
| 67 |
}
|
| 68 |
|
| 69 |
const spaceCache = new SpaceCache();
|
| 70 |
|
| 71 |
// 用于获取 Spaces 数据的函数,带有重试机制
|
| 72 |
-
async function fetchSpacesWithRetry(username, token, maxRetries =
|
| 73 |
let retries = 0;
|
| 74 |
while (retries < maxRetries) {
|
| 75 |
try {
|
|
|
|
| 76 |
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
|
| 77 |
const response = await axios.get(`https://huggingface.co/api/spaces?author=${username}`, {
|
| 78 |
headers,
|
| 79 |
timeout: 10000 // 设置 10 秒超时
|
| 80 |
});
|
| 81 |
const spaces = response.data;
|
| 82 |
-
console.log(`获取到 ${spaces.length} 个 Spaces for ${username} (尝试 ${retries + 1}/${maxRetries})`);
|
| 83 |
return spaces;
|
| 84 |
} catch (error) {
|
| 85 |
retries++;
|
|
@@ -89,7 +89,7 @@ async function fetchSpacesWithRetry(username, token, maxRetries = 5, retryDelay
|
|
| 89 |
} else if (error.request) {
|
| 90 |
errorDetail += ', No response received (possible network issue)';
|
| 91 |
}
|
| 92 |
-
console.error(`获取 Spaces 列表失败 for ${username} (尝试 ${retries}/${maxRetries}): ${errorDetail}`);
|
| 93 |
if (retries < maxRetries) {
|
| 94 |
console.log(`等待 ${retryDelay/1000} 秒后重试...`);
|
| 95 |
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
@@ -207,6 +207,7 @@ app.get('/api/proxy/spaces', async (req, res) => {
|
|
| 207 |
const spaces = await fetchSpacesWithRetry(username, token);
|
| 208 |
for (const space of spaces) {
|
| 209 |
try {
|
|
|
|
| 210 |
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
|
| 211 |
const spaceInfoResponse = await axios.get(`https://huggingface.co/api/spaces/${space.id}`, { headers });
|
| 212 |
const spaceInfo = spaceInfoResponse.data;
|
|
@@ -227,11 +228,11 @@ app.get('/api/proxy/spaces', async (req, res) => {
|
|
| 227 |
app_port: spaceInfo.cardData?.app_port || 'unknown'
|
| 228 |
});
|
| 229 |
} catch (error) {
|
| 230 |
-
console.error(`处理 Space ${space.id} 失败:`, error.message);
|
| 231 |
}
|
| 232 |
}
|
| 233 |
} catch (error) {
|
| 234 |
-
console.error(`获取 Spaces 列表失败 for ${username}:`, error.message);
|
| 235 |
}
|
| 236 |
}
|
| 237 |
|
|
@@ -459,6 +460,7 @@ class MetricsConnectionManager {
|
|
| 459 |
|
| 460 |
const instanceId = repoId.split('/')[1];
|
| 461 |
const url = `https://api.hf.space/v1/${username}/${instanceId}/live-metrics/sse`;
|
|
|
|
| 462 |
const headers = token ? {
|
| 463 |
'Authorization': `Bearer ${token}`,
|
| 464 |
'Accept': 'text/event-stream',
|
|
@@ -515,7 +517,7 @@ class MetricsConnectionManager {
|
|
| 515 |
});
|
| 516 |
|
| 517 |
this.connections.set(repoId, stream);
|
| 518 |
-
console.log(`已建立监控连接 (${repoId})`);
|
| 519 |
return stream;
|
| 520 |
} catch (error) {
|
| 521 |
console.error(`无法连接到监控端点 (${repoId}):`, error.message);
|
|
@@ -668,18 +670,6 @@ app.post('/api/proxy/update-subscriptions', (req, res) => {
|
|
| 668 |
res.json({ success: true, message: '订阅列表已更新' });
|
| 669 |
});
|
| 670 |
|
| 671 |
-
// 强制刷新缓存的接口
|
| 672 |
-
app.post('/api/proxy/refresh-spaces', async (req, res) => {
|
| 673 |
-
try {
|
| 674 |
-
console.log('前端请求强制刷新 Spaces 缓存');
|
| 675 |
-
spaceCache.invalidate(); // 使缓存失效
|
| 676 |
-
res.json({ message: '缓存已失效,数据将被重新获取' });
|
| 677 |
-
} catch (error) {
|
| 678 |
-
console.error('强制刷新缓存失败:', error.message);
|
| 679 |
-
res.status(500).json({ error: '强制刷新缓存失败', details: error.message });
|
| 680 |
-
}
|
| 681 |
-
});
|
| 682 |
-
|
| 683 |
// 处理其他请求,重定向到 index.html
|
| 684 |
app.get('*', (req, res) => {
|
| 685 |
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
|
|
|
| 61 |
}
|
| 62 |
|
| 63 |
invalidate() {
|
| 64 |
+
this.lastUpdate = null;
|
|
|
|
| 65 |
}
|
| 66 |
}
|
| 67 |
|
| 68 |
const spaceCache = new SpaceCache();
|
| 69 |
|
| 70 |
// 用于获取 Spaces 数据的函数,带有重试机制
|
| 71 |
+
async function fetchSpacesWithRetry(username, token, maxRetries = 3, retryDelay = 2000) {
|
| 72 |
let retries = 0;
|
| 73 |
while (retries < maxRetries) {
|
| 74 |
try {
|
| 75 |
+
// 仅在 token 存在时添加 Authorization 头
|
| 76 |
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
|
| 77 |
const response = await axios.get(`https://huggingface.co/api/spaces?author=${username}`, {
|
| 78 |
headers,
|
| 79 |
timeout: 10000 // 设置 10 秒超时
|
| 80 |
});
|
| 81 |
const spaces = response.data;
|
| 82 |
+
console.log(`获取到 ${spaces.length} 个 Spaces for ${username} (尝试 ${retries + 1}/${maxRetries}),使用 ${token ? 'Token 认证' : '无认证'}`);
|
| 83 |
return spaces;
|
| 84 |
} catch (error) {
|
| 85 |
retries++;
|
|
|
|
| 89 |
} else if (error.request) {
|
| 90 |
errorDetail += ', No response received (possible network issue)';
|
| 91 |
}
|
| 92 |
+
console.error(`获取 Spaces 列表失败 for ${username} (尝试 ${retries}/${maxRetries}): ${errorDetail},使用 ${token ? 'Token 认证' : '无认证'}`);
|
| 93 |
if (retries < maxRetries) {
|
| 94 |
console.log(`等待 ${retryDelay/1000} 秒后重试...`);
|
| 95 |
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
|
|
| 207 |
const spaces = await fetchSpacesWithRetry(username, token);
|
| 208 |
for (const space of spaces) {
|
| 209 |
try {
|
| 210 |
+
// 仅在 token 存在时添加 Authorization 头
|
| 211 |
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
|
| 212 |
const spaceInfoResponse = await axios.get(`https://huggingface.co/api/spaces/${space.id}`, { headers });
|
| 213 |
const spaceInfo = spaceInfoResponse.data;
|
|
|
|
| 228 |
app_port: spaceInfo.cardData?.app_port || 'unknown'
|
| 229 |
});
|
| 230 |
} catch (error) {
|
| 231 |
+
console.error(`处理 Space ${space.id} 失败:`, error.message, `使用 ${token ? 'Token 认证' : '无认证'}`);
|
| 232 |
}
|
| 233 |
}
|
| 234 |
} catch (error) {
|
| 235 |
+
console.error(`获取 Spaces 列表失败 for ${username}:`, error.message, `使用 ${token ? 'Token 认证' : '无认证'}`);
|
| 236 |
}
|
| 237 |
}
|
| 238 |
|
|
|
|
| 460 |
|
| 461 |
const instanceId = repoId.split('/')[1];
|
| 462 |
const url = `https://api.hf.space/v1/${username}/${instanceId}/live-metrics/sse`;
|
| 463 |
+
// 仅在 token 存在且非空时添加 Authorization 头
|
| 464 |
const headers = token ? {
|
| 465 |
'Authorization': `Bearer ${token}`,
|
| 466 |
'Accept': 'text/event-stream',
|
|
|
|
| 517 |
});
|
| 518 |
|
| 519 |
this.connections.set(repoId, stream);
|
| 520 |
+
console.log(`已建立监控连接 (${repoId}),使用 ${token ? 'Token 认证' : '无认证'}`);
|
| 521 |
return stream;
|
| 522 |
} catch (error) {
|
| 523 |
console.error(`无法连接到监控端点 (${repoId}):`, error.message);
|
|
|
|
| 670 |
res.json({ success: true, message: '订阅列表已更新' });
|
| 671 |
});
|
| 672 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 673 |
// 处理其他请求,重定向到 index.html
|
| 674 |
app.get('*', (req, res) => {
|
| 675 |
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|