【问题标题】:Firebase Functions Event Source stuck on pendingFirebase 函数事件源卡在待处理状态
【发布时间】:2020-11-05 12:38:53
【问题描述】:

我正在尝试使用 事件发射器 来触发我需要的特定功能。这是 nodejs 代码。 事件源在 localhost 上本地运行,但部署后,我无法检测到事件触发器。但是,firebase 函数记录器上的日志显示正在执行的函数。但是,在测试时,该函数不会向事件提供任何反馈

const EventEmitter = require('events');

const Stream = new EventEmitter();

// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE',

exports.eventEmitter = (req, res) => {
    console.log(req.body);
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        Connection: 'keep-alive'
    })

    Stream.on('push', function(event, data) {
        console.log('send0');
        res.write('event: ' + String(event) + '\n' + 'data:' + JSON.stringify(data) + '\n\n');
    });

    setInterval(() => {
        console.log('send1');
        Stream.emit('push', 'message', { msg: 'it works! hurraaay' });
    }, 5000);

}

当我使用以下 Angular 代码在本地测试此代码以进行事件发射时,该事件在控制台上检测到并记录。但是,一旦我将该功能部署到 firebase 功能,我会在浏览器的网络选项卡上收到一个 待处理的请求,它没有任何日志并且似乎没有在全部,我的角度代码不可避免地什么也没检测到

getStream() {
    return Observable.create(observer => {
      let url = 'link to emitter';
      let eventSource = new EventSource(url);

      eventSource.addEventListener('message', function(e) {
        console.log(e.data);
      }, false);
      
      eventSource.addEventListener('open', function(e) {
        // Connection was opened.
        console.log("open");
      }, false);
      
      eventSource.addEventListener('error', function(e) {
        if (eventSource.readyState == EventSource.CLOSED) {
          // Connection was closed.
          console.log("closed");
        }
      }, false);
      eventSource.addEventListener('message', message => { console.log(message.data); });

      eventSource.onmessage = (event) => {
        let json = JSON.parse(event.data);
        if (json !== undefined && json !== '') {
          this.zone.run(() => observer.next(json));
        }
      };

      eventSource.onerror = (error) => {
        if (eventSource.readyState === 0) {
          console.log('The stream has been closed by the server.');
          eventSource.close();
          observer.complete();
        } else {
          observer.error('EventSource error: ' + error);
        }
      }
    });
  }

【问题讨论】:

    标签: javascript node.js google-cloud-functions event-sourcing eventemitter


    【解决方案1】:

    Cloud Functions HTTP 端点不支持向客户端(如 websocket)流式传输数据。它只能预先接收整个有效负载,然后将整个有效负载发送回客户端。没有分块响应。有效负载的限制为 10MB。函数调用的默认超时时间是 60 秒,最多只能增加到 9 米。如果您需要流式传输,那么 Cloud Functions 不适合您的用例。

    【讨论】:

    • 如果我把它变成一个 web socket 会可行吗??
    • AWS lambda 是否适用于类似的参数/原理?什么是可行的选择??
    • 我不知道 - 你应该研究你的选择。 Stack Overflow 不是获取产品推荐的地方。
    • 我让服务器端事件在 Cloud Functions 上工作,但事件似乎不会在发生时发送到客户端。当我在本地运行它时,我会在事件发生时一次获得一个事件。但是在部署到 Cloud Functions 后,服务器会将它们全部保存起来,并在所有操作完成后一次性发送。对于获取长时间操作的进度更新不是超级有用(我的用例)。您可能想尝试长轮询。我还没有尝试过,但这是我唯一没有尝试过的东西。 WebSockets 在 Cloud Functions 上根本不起作用。
    猜你喜欢
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 2020-12-14
    • 2021-11-18
    • 1970-01-01
    • 2017-10-11
    相关资源
    最近更新 更多