Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error using socket.io along with webpack-dev-server

Quick question guys, I am trying to use webpack-dev-server with socketio, but after trying different things, i figured both of the clients are listening to the same port '3000' and I end up with some kind of handshake error that goes away if I dont use webpack-dev-server on the same port.. here is my server config

const PORT = process.env.PORT || 3000;

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
  setup(app) {

    const server = require('http').Server(app);
    let onlineUsers = 0;
    const io = require('socket.io')(server);

    io.on('connection', (socket) => {
      console.log(`A client is connected:${socket.id}`);
      onlineUsers++;
      io.sockets.emit('onlineUsers', {
        onlineUsers
      });
    });

    server.listen(3000, () => {
      console.log('listening on *:3000');
    });
  }
}).listen(PORT, 'localhost', (err) => {
  if (err) {
    console.log(err);
  }
  console.log(`Listening at localhost: ${PORT}`);
});

and webpack config

  entry: [
    'webpack-dev-server/client?http://localhost:3000',
    'webpack/hot/only-dev-server',
    'react-hot-loader/patch',
    './src/app.js'
  ],

these are the error(s)

WebSocket connection to 'ws://localhost:3000/sockjs-
node/608/jsbr0a0r/websocket' failed: Connection closed 
before receiving a handshake response

T http://localhost:3000/sockjs-node/225/qvolyk2n/eventsource 
iframe.js?ea3f:102 GET http://localhost:3000/sockjs-node/iframe.html 404 (Not Found)
createIframe @ iframe.js?ea3f:102
IframeTransport @ iframe.js?7dcb:42
IframeWrapTransport @ iframe-wrap.js?7e29:11
SockJS._connect @ main.js?45b8:219
SockJS._transportClose @ main.js?45b8:299
g @ emitter.js?927b:30
EventEmitter.emit @ emitter.js?927b:50
(anonymous) @ sender-receiver.js?620a:28
g @ emitter.js?927b:30
EventEmitter.emit @ emitter.js?927b:50
(anonymous) @ polling.js?97d6:41
g @ emitter.js?927b:30
EventEmitter.emit @ emitter.js?927b:50
(anonymous) @ eventsource.js?d407:58
VM776:66[HMR] Waiting for update signal from WDS...
VM1157:49Warning: [react-router] Location "/sockjs-node/225/ucoowxum/htmlfile?c=_jp.alfvbqm" did not match any routes

I was trying is to proxy the request to a different port

proxy: {
  "http://localhost:3000": "http://localhost:4000"
}

and then listen to that in the configurations

  entry: [
    'webpack-dev-server/client?http://localhost:4000',
    'webpack/hot/only-dev-server',
    'react-hot-loader/patch',
    './src/app.js'
  ],

but I don't know if that is the way to go, anyone know how to fix this?

like image 719
xtabbas Avatar asked Mar 05 '17 17:03

xtabbas


1 Answers

The issue is your proxy is not correctly configured. By default when you call the socket.io constructor, this line

const io = require('socket.io')(server);

All socket.io requests will go to your webpack dev server http://localhost:3000/socket.io (note the end of the URL - important) in your case. You want to proxy those requests to http://localhost:4000/socket.io, not every request that hits http://localhost:3000. You're also missing the ws: true line. So actually the correct configuration is the following:

proxy: {
    '/api': {
        target: 'http://localhost:4000',
        pathRewrite: {"^/api": ""}
    },
    '/socket.io': {
        target: 'http://localhost:4000',
        ws: true
    }
}

You don't need the first '/api' part if you don't have have a backend API that is listening to other requests. I'm just assuming you do. It's possible you just have all sockets in which case you can ignore that line. In most cases, people will have sockets and other http requests.

Hope this helps anyone trying to set up webpack-dev-server and socket.io with a proxy.

like image 93
coolboyjules Avatar answered Oct 25 '22 08:10

coolboyjules