How to use socket.io together with webpack-hot-middleware?
Asked Answered
D

1

21

I have a Koa server using webpack-dev-middleware and webpack-hot-middleware doing hot module replacement (HMR), so the middleware uses a websocket to push changes to the client.

But my application code also needs its own websocket connection between the client and the Koa server. I have no idea how to achieve that? Seems like the two are conflicting. Can I have them side by side?

My server code looks something like this

const compiler = webpack(webpackConfig)
const app = new Koa()

app.use(webpackDevMiddleware(compiler, {
  quiet: true,
  noInfo: true
  stats: {
    colors: true,
    reasons: true
  }
})))

app.use(webpackHotMiddleware(compiler))

const server = require('http').createServer(app.callback())
const io = require('socket.io')(server)
io.on('connection', function() { console.log('socket connection!!') })

And my client something like

import Client from 'socket.io-client'
const io = Client()
io.on('connection', (socket) => {
  console.log('+++ io connected! ++++')
  io.on('disconnect', () => { console.log('disconnected', socket) })
})

The HMR socket is working correctly, but the other one is trying to talk to GET /socket.io/?EIO=3&transport=polling&t=1446911862461-0 and those requests are failing.

How do I create a websocket that doesn't clash with the HMR socket?

Diaconate answered 7/11, 2015 at 16:2 Comment(1)
How did you fix this? I am running into a similar issue where the Express code works but the Koa one always yields a 404Byssinosis
M
12

Here's what worked for me in an app I'm working on where I'm using webpack hot reloading + socket.io on the same express server.

Additions to your package.json:

"webpack-dev-middleware": "^1.4.0",
"webpack-hot-middleware": "^2.6.0"

In the plugins section of your webpack config:

plugins: [
   new webpack.optimize.OccurenceOrderPlugin(),
   new webpack.HotModuleReplacementPlugin(),
   new webpack.NoErrorsPlugin(),
],

Setup for the express app:

const http = require('http');
const express = require('express');

const webpack = require('webpack');
const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);

// Create the app, setup the webpack middleware
const app = express();
app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: webpackConfig.output.publicPath,
}));
app.use(require('webpack-hot-middleware')(compiler));

// You probably have other paths here
app.use(express.static('dist'));

const server = new http.Server(app);
const io = require('socket.io')(server);

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

server.listen(PORT);

io.on('connection', (socket) => {
  // <insert relevant code here>
  socket.emit('mappy:playerbatch', playerbatch);
});

I posted a bounty for this question to help this question get answered, though I've got it working for my own app.

Marking answered 29/12, 2015 at 3:43 Comment(3)
So you didn't have to do anything special? It looks like regular express + socket.io code to me. I ended up using engine.io (the underlying library in socket.io) because I realized I only needed a websocket and not the fallback mechanism. That worked without problems.Diaconate
The ordering of when the middleware was placed certainly affected me.Marking
I didn't know that makes a difference. Thanks!Diaconate

© 2022 - 2024 — McMap. All rights reserved.