问题
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?
回答1:
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.
回答2:
just to be thorough, here's the full nodejs implementation of it. nodejs:
const http = require("http").createServer(app);
const io = require('socket.io')(http);
io.set('transports', ['websocket']);
http.listen(3002, () => console.log(`socket: http://${ip.address()}:3002`, "Time:", moment(new Date().getTime()).format("DD日 h:mm:ss")));
frontend:
var server = "/";
var connectionOptions = {
"force new connection": true,
"reconnectionAttempts": "Infinity", //avoid having user reconnect manually in order to prevent dead clients after a server restart
"timeout": 10000, //before connect_error and connect_timeout are emitted.
"transports": ["websocket"]
};
store.state.socket = io(server, connectionOptions);
store.state.socket.on('connect', () => {
console.log('socket connected ----');
});
webpack:
const target = "http://" + "localhost" + ":" + "3001";
const socket = "http://" + "localhost" + ":" + "3002";
module.exports = {
devServer: {
https: true,
key: fs.readFileSync('./src/localhostcert/key.pem'),
cert: fs.readFileSync('./src/localhostcert/cert.pem'),
host: 'localhost',
hot: true,
compress: true,
port: 8080,
proxy: {
"/socket.io": {
target: socket,
ws: true
}
}
}
}
来源:https://stackoverflow.com/questions/42611926/error-using-socket-io-along-with-webpack-dev-server