Tom Söderlund
Tom Söderlund

Reputation: 4747

Socket.io cannot connect, resorts to "polling"

I'm trying to create a websocket client-server app where client and server will run on two different instances.

Setup

Client and server

Server

Note: not complete code, but the pieces I think are relevant.

// ----- socketio.js -----

// When the user connects.. perform this
function onConnect(socket) {
    // When the client emits 'info', this listens and executes
    socket.on('info', function (data) {
        console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2));
        socket.emit('pong', 'OK!');
    });
    // Insert sockets below
    require('../api/thing/thing.socket').register(socket);
}

socketio.set('origins', 'http://localhost:9007');

// ----- express.js -----

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:9007');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});

// ----- app.js -----

// Start server
server.listen(config.port, config.ip, function () {
  console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

Client

// ----- client app.js

angular
.module('weldCommentsClientApp', [
    'ngAnimate', 'ngAria', 'ngCookies', 'ngMessages', 'ngResource', 'ngRoute', 'ngSanitize', 'ngTouch',
    'btford.socket-io'
])
.factory('mySocket', function (socketFactory) {
    var myIoSocket = window.io.connect('http://localhost:9006');
    var mySocket = socketFactory({
        ioSocket: myIoSocket
    });
    mySocket.forward('pong');
    console.log('mySocket', mySocket);
    return mySocket;
})

// ----- client main.js

angular.module('weldCommentsClientApp').controller('MainCtrl', function ($scope, mySocket) {
    $scope.$on('socket:pong', function (ev, data) {
        console.log('socket:pong', ev, data);
    });
    mySocket.emit('info');
});

Results

No console errors on server nor client, but it doesn't work and the server logs 100's of these lines:

GET /socket.io/?EIO=3&transport=polling&t=1421488528935-16027 200 2ms

...which looks like the client connects over HTTP but fails to switch over to websockets.

Any ideas?

Update

Here is the entire client/server project with instructions in README: https://github.com/weld-io/socket.io-client-server-boilerplate

Upvotes: 14

Views: 22726

Answers (5)

williamsi
williamsi

Reputation: 1606

Late answer but maybe this'll help someone.

If you are using reverse proxy on nginx, you'll need additional proxy_http_version, proxy_set_header(s) in your server nginx block.

# example ssl nginx block
server {
    listen 443 ssl;
    server_name domain.com;
    ssl_certificate /etc/ssl/certs/domain.com.pem;
    ssl_certificate_key /etc/ssl/private/domain.com.key;

    location / {
        proxy_pass http://localhost:8888; # your server port
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header Origin $http_origin;
        proxy_set_header Referer $http_referer;
    }
}

Upvotes: 0

leszek.hanusz
leszek.hanusz

Reputation: 5327

The path is not defined correctly in server/app.js

Try to use '/socket.io' path like this:

var socketio = require('socket.io')(server, {
  serveClient: (config.env === 'production') ? false : true,
  path: '/socket.io'
});

Next, to choose websockets instead of long-polling, you can select the websocket transport in test-client/scripts/application.js

var myIoSocket = window.io.connect('http://localhost:9006', {transports:['websocket']});

Upvotes: 21

ahmed.hoban
ahmed.hoban

Reputation: 516

Could try 2 things: first change

window.io.connect('http://... 

to

window.io.connect('ws://...

Secondly on server side set

socketio.set('transports',['xhr-polling']);

I know that looks incorrect, since you want to avoid polling, still it helped a lot of people who had the same problem.

Upvotes: 0

Jean-Baptiste Louazel
Jean-Baptiste Louazel

Reputation: 525

I think it's because your server are using sockets on http://localhost:9007 and your client on http://localhost:9006. Try to put both on the same port, it should work.

Upvotes: 0

John Hua
John Hua

Reputation: 1456

I suggest you test client-server respectively. nc will be an ideal alternative for this kind of situation.

  1. start server and echo testserver | nc server_ip server_port and check server log.

  2. start client and netcat -l -p server_port and check client log.

BTW, the client code you've showed doesn't seem to attempt to connect to the server.

Upvotes: 0

Related Questions