You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js结合Socket.io实现多API调用流式数据传输技术咨询

Great question! Socket.io is absolutely a strong candidate for this scenario, and there are also a couple of other straightforward options that keep all the logic server-side as you requested. Let’s break down your best choices:

Option 1: Socket.io (WebSocket-based)

Socket.io is perfect here because it handles WebSocket compatibility out of the box (with fallbacks like long polling for older environments) and lets your server push partial results to the client the moment each API call finishes. All the orchestration happens on the server—no extra client-side logic beyond listening for incoming data.

Step 1: Set up Socket.io on your Node.js server

First, install the dependency:

npm install socket.io axios express

Then implement the server logic to fetch API data and stream results:

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const axios = require('axios');

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "http://your-angular-client-url", // Replace with your Angular app's URL
    methods: ["GET", "POST"]
  }
});

io.on('connection', (socket) => {
  console.log('Client connected to socket');

  // Listen for the client's request to start fetching data
  socket.on('init-data-stream', async () => {
    const apiEndpoints = [
      'https://api.example.com/data-set-1',
      'https://api.example.com/data-set-2',
      'https://api.example.com/data-set-3'
    ];

    try {
      // Run API calls in parallel and push results as they come in
      const apiPromises = apiEndpoints.map(async (url) => {
        const response = await axios.get(url);
        return { source: url, payload: response.data };
      });

      // Stream each result the moment its promise resolves
      for (const promise of apiPromises) {
        const result = await promise;
        socket.emit('partial-data', result);
      }

      // Signal the client that all data has been sent
      socket.emit('stream-complete', { message: 'All API results delivered' });
    } catch (err) {
      // Send error details if any API call fails
      socket.emit('stream-error', { error: err.message });
    }
  });

  socket.on('disconnect', () => {
    console.log('Client disconnected from socket');
  });
});

server.listen(3000, () => {
  console.log('Server running on port 3000');
});

Step 2: Angular client setup (minimal logic)

Your Angular app only needs to connect to the socket, trigger the stream, and listen for incoming data:

import { Component, OnInit } from '@angular/core';
import { io } from 'socket.io-client';

@Component({
  selector: 'app-data-display',
  templateUrl: './data-display.component.html'
})
export class DataDisplayComponent implements OnInit {
  private socket: any;
  collectedResults: any[] = [];
  streamFinished = false;
  errorMsg = '';

  ngOnInit() {
    this.socket = io('http://your-server-url:3000');

    // Handle partial results from the server
    this.socket.on('partial-data', (data: any) => {
      this.collectedResults.push(data);
    });

    // Handle stream completion
    this.socket.on('stream-complete', () => {
      this.streamFinished = true;
    });

    // Handle errors
    this.socket.on('stream-error', (error: any) => {
      this.errorMsg = error.error;
    });

    // Trigger the server to start the data stream
    this.socket.emit('init-data-stream');
  }
}
Option 2: Server-Sent Events (SSE)

If you don’t need two-way communication (you only need the server to push data to the client), SSE is a lighter, HTTP-based alternative. It’s a standard web feature, so no extra WebSocket libraries are required.

Server-side implementation (Express)

const express = require('express');
const axios = require('axios');
const app = express();

app.get('/api/stream-data', async (req, res) => {
  // Set SSE-specific headers
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('Access-Control-Allow-Origin', 'http://your-angular-client-url');

  const apiEndpoints = [
    'https://api.example.com/data-set-1',
    'https://api.example.com/data-set-2',
    'https://api.example.com/data-set-3'
  ];

  try {
    // Fetch and stream results in parallel
    const apiPromises = apiEndpoints.map(async (url) => {
      const response = await axios.get(url);
      return { source: url, payload: response.data };
    });

    for (const promise of apiPromises) {
      const result = await promise;
      // Send the result as an SSE message
      res.write(`data: ${JSON.stringify(result)}\n\n`);
      // Ensure data is flushed immediately
      await new Promise(resolve => setTimeout(resolve, 50));
    }

    // Send completion signal
    res.write(`data: ${JSON.stringify({ type: 'complete', message: 'Stream finished' })}\n\n`);
    res.end();
  } catch (err) {
    res.write(`data: ${JSON.stringify({ type: 'error', error: err.message })}\n\n`);
    res.end();
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Angular client setup for SSE

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-data-display',
  templateUrl: './data-display.component.html'
})
export class DataDisplayComponent implements OnInit {
  collectedResults: any[] = [];
  streamFinished = false;
  errorMsg = '';

  ngOnInit() {
    const eventSource = new EventSource('http://your-server-url:3000/api/stream-data');

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);
      if (data.type === 'complete') {
        this.streamFinished = true;
        eventSource.close();
      } else if (data.type === 'error') {
        this.errorMsg = data.error;
        eventSource.close();
      } else {
        this.collectedResults.push(data);
      }
    };

    eventSource.onerror = () => {
      console.error('SSE connection failed');
      eventSource.close();
    };
  }
}
Which Option Should You Pick?
  • Go with Socket.io if you might need two-way communication later (e.g., letting the client cancel the stream mid-process) or need better compatibility with older browsers.
  • Go with SSE if you want a lightweight, standards-based solution that only requires HTTP (no WebSocket overhead) and don’t need two-way communication.

Both options keep all the data-fetching and orchestration logic on your Node.js server, exactly as you requested.

内容的提问来源于stack exchange,提问作者Naufal Khalid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:22:32