简体   繁体   中英

NodeJS server on DigitalOcean using socket.io returns connection refused

I was trying to introduce socket.io to my application developed in Laravel and in AngularJS.
The application works fine in my computer, nevertheless when I try to make it work on the server I get the error ' GET http://localhost:8080/socket.io/?EIO=3&transport=polling&t=LQxpNjO .net::ERR_CONNECTION_REFUSED '.

The server is running Ubuntu 16.04 and I am using nginx as a web server.

This is the file which creates the nodejs server:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();

var port = 8080;

http.listen(port, function() {
  console.log('Listening on *:' + port);
});

io.on('connection', function (socket) {

  console.info('Client connected');

  redis.subscribe('counter.increase');

  redis.on('message', function (channel, message) {
    console.log('Received message ' + message + ' in channel ' + channel);

    socket.emit(channel, message);
  });

  socket.on('disconnect', function() {
    console.info('Client disconnected');
  });

});

This is the AngularJS factory that should connect to the nodejs server. Here I am using angular-socket.io:

angular.module('myServices').factory('socket', function (socketFactory) {
  var ioSocket = io.connect('http://localhost:8080');

  socket = socketFactory({
    ioSocket: ioSocket
  });

  return socket;
});

This is the configuration file of nginx (/etc/nginx/sites-available/default):

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html/public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name XXX.XXX.XXX.XXX;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

How could I solve this problem?


Update 1

I updated the nginx configuration file like this:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html/public;

    index index.php index.html index.htm index.nginx-debian.html;
    server_name XXX.XXX.XXX.XXX;
    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~* \.io {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location ~ /\.ht {
        deny all;
    }
}

upstream app_yourdomain {
    server 127.0.0.1:3000;
    keepalive 8;
}

and the AngularJS factory like this:

angular.module('myServices').factory('socket', function (socketFactory) {
  var ioSocket = io.connect('http://localhost:8080/socket.io');

  socket = socketFactory({
    ioSocket: ioSocket
  });

  return socket;
});

Now i get the following error:
- GET http://example.com/bower_components/socket.io-client/socket.io.js


Update 2

These are my nginx configuration file:

upstream app_example.com {
    server 127.0.0.1:3000;
    keepalive 8;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html/public;

    index index.php index.html index.htm index.nginx-debian.html;

    server_name XXX.XXX.XXX.XXX;

    location / {
        # First attempt to serve request as file, then as
        # directory, then fall back to displaying a 404.
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ ^/(socket\.io) {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location ~ /\.ht {
        deny all;
    }
}

and the AngularJS factory:

angular.module('myServices').factory('socket', function (socketFactory) {
  var ioSocket = io.connect('http://localhost');

  socket = socketFactory({
    ioSocket: ioSocket
  });

  return socket;
});




Working solution

Thanks to John I finally managed to make the application work.

This is nginx configuration file:

upstream app_example.com {
    server 127.0.0.1:3000;
    keepalive 8;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html/public;

    index index.php index.html index.htm index.nginx-debian.html;

    server_name XXX.XXX.XXX.XXX;
    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ ^/(socket\.io) {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location ~ /\.ht {
        deny all;
    }
}

This is the AngularJS factory:

angular.module('myServices').factory('socket', function (socketFactory) {
  var ioSocket = io.connect('http://example.com');

  socket = socketFactory({
    ioSocket: ioSocket
  });

  return socket;
});

This is the nodejs server:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();

var port = 3000;

http.listen(port, function() {
  console.log('Listening on *:' + port);
});

io.on('connection', function (socket) {

  console.info('Client connected');

  redis.subscribe('counter.increase');

  redis.on('message', function (channel, message) {
    console.log('Received message ' + message + ' in channel ' + channel);

    socket.emit(channel, message);
  });

  socket.on('disconnect', function() {
    console.info('Client disconnected');
  });

});

Socket.io use /socket.io after your domaine name. Then you have to specify the socket.io location :

location ~* \.io {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;        
}

And don't forget the upstream for your node js app

upstream app_yourdomain {
    server 127.0.0.1:3000;
    keepalive 8;
}

For anyone else who is might be trying to figure this out like me, I just got this working after 4 hours of trying on a digital ocean server.

Follow the working solution that OP edited into the answer solved half of it, however I had to use a cdn for the links inside my html files.

Here's the cdn's to choose from https://cdnjs.com/libraries/socket.io . Pick one and replace the url in <script src="http://localhost:3000/socket.io/socket.io.js"></script> with the cdn on the pages where you need it.

For my client side javascript (or angular in this case), just use the public domain name that you want to connect to the app with.

Also, make sure you add the the stuff you don't have in your nginx setup that OP wrote in the working answer. No need for the php section unless you're using php. I'm not so I omitted it. Make sure that you replace 'app_example.com' with the same address or domain that you used in your client side javascript.

This probably isn't the right place to post this but I can't comment yet and I don't want other people going through 4 hours of trial and error.

John's answer is correct. In case someone is looking for extra info. Suggesting that your localhost is on 9000 at EC2, with React framework for front-end.

Project structure

  • your-project-folder/api/app.js
  • your-project-folder/client/src/socket.js

Client(===your-project-folder/client/src/socket.js):

import { io } from "socket.io-client"; // make sure you have npm i socket.io-client under "your-project-folder/client"
export const socket = io.connect('https://yourdomain'); // production
// Develop: export io.connect('http://localhost:9000');

You do NOT need <script src="%PUBLIC_URL%/socket.io/socket.io.js"></script> under client/public/index.html because you access socket client from import { io } from "socket.io-client"; ...which is from your node_modules under your client/ folder.

And under server/ section inside /etc/nginx/nginx.conf

# Connect to socket io server
location ~* \.io {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header Connection 'upgrade';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM