Dezmen Ceo Sykes
Dezmen Ceo Sykes

Reputation: 301

Problems connecting to socket.io using firebase functions and express

I'm trying to utilize a socket.io connection with firebase hosting/functions but I'm running into a few problems. It started off as a CORS issue (which im sure is still the problem) but now I'm just totally lost on whats wrong, below is my firebase.json, index.js (firebase function file), and even the angular client file which initializes the connection to the server.

firebase.json

{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [ 

      {
        "source" : "**",
        "headers" : [ {
          "key" : "Access-Control-Allow-Headers",
          "value" : "Origin"
        } ]
      },
      {
        "source" : "**",
        "headers" : [ {
          "key" : "Access-Control-Allow-Origin",
          "value" : "http://localhost:4200"
        } ]
      }
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "app"
      }
    ]
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint"
    ],
    "source": "functions"
  }
}

index.js

const functions = require('firebase-functions');
const express = require('express');
var app = express();

const http = require('http').Server(express);
const socketio = require('socket.io')(http);
const cors = require('cors');


app.use(cors({credentials: true, origin: '*:*'}));
app.get('/tester', (request, response) => {

    //response.header('Access-Control-Allow-Origin', '*');
    response.send('Hello!');

    socketio.on('connection', socket => {
        connections.push(socket);
        console.log('New client connected ('+connections.length+' connections).');
        //console.log(socket);
        socket.emit('port', 'LIVE SHIT');
    });
})

exports.app = functions.https.onRequest(app)

app.component.ts (client component for connection)

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'multi-client';
  port: number = 0;
  socket: any;
  width: number = 100;
  updateVal: number = 5;
  constructor()
  {
    this.socket = io('http://localhost:5000/tester');

    this.socket.on('port', port => {
      this.port = port;
    })
  }

  updateWidth(val)
  {
    this.width += val;
  }
}

This is the error I'm getting. enter image description here

I viewed a few posts on stackoverflow and various other sites that had similar problems but nothing seemed to work. I'm sure im doing it wrong but I'm lost on what I'm missing to accomplish this. Please help!

Upvotes: 2

Views: 1423

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599101

Cloud Functions are for relatively short-lived operations with a clear end. You cannot use Cloud Functions to keep a connection to the client open.

The reason is that Cloud Functions closes the resources of your container by the time it thinks you're done. In the case of a HTTP function like yours, that means that these resources are gone when you've called response.send('Hello!');.

So what is possible is to send the response to the client once you've established a socket connection like this:

app.get('/tester', (request, response) => {


    socketio.on('connection', socket => {
        connections.push(socket);
        console.log('New client connected ('+connections.length+' connections).');
        //console.log(socket);
        socket.emit('port', 'LIVE SHIT');

        response.send('Hello!');
    });
})

But in that case too, the connection will be closed after the call to response.send('Hello!');. And while you could not send a response, even in that case the connection/resources will be closed after 9 minutes, since that is the maximum time a Cloud Function can run.

It all goes back to my initial statement that Cloud Functions are only for short-lived operations with a clear end moment. For long-running processes, use another platform, such as App Engine, Compute Engine, or one of the many other offerings where you can manage your own processes.

Also see:

Upvotes: 2

Related Questions