快速问题的人,我正在尝试使用带有socketio的webpack-dev-server,但在尝试不同的事情之后,我认为两个客户端都在听同一个端口'3000',我最终得到了某种握手如果我不在同一个端口上使用webpack-dev-server,那就消失了。这是我的服务器配置
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}`);
});
和webpack config
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./src/app.js'
],
这些是错误
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
我试图将请求代理到另一个端口
proxy: {
"http://localhost:3000": "http://localhost:4000"
}
然后在配置中听取
entry: [
'webpack-dev-server/client?http://localhost:4000',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./src/app.js'
],
但我不知道这是否可行,有谁知道如何解决这个问题?
答案 0 :(得分:9)
问题是您的代理未正确配置。默认情况下,当您调用socket.io
构造函数时,此行
const io = require('socket.io')(server);
所有socket.io请求都将转到您的webpack dev服务器http://localhost:3000/socket.io(请注意URL的结尾 - 重要)。您希望将那些请求代理到http://localhost:4000/socket.io,而不是每次点击http://localhost:3000的请求。您还错过了ws: true
行。所以实际上正确的配置如下:
proxy: {
'/api': {
target: 'http://localhost:4000',
pathRewrite: {"^/api": ""}
},
'/socket.io': {
target: 'http://localhost:4000',
ws: true
}
}
如果您没有正在侦听其他请求的后端API,则不需要第一个'/api'
部分。我只是假设你这样做。您可能只有所有套接字,在这种情况下您可以忽略该行。在大多数情况下,人们会有套接字和其他http请求。
希望这可以帮助任何尝试使用代理设置webpack-dev-server
和socket.io
的人。
答案 1 :(得分:0)
为了更全面,这是它的完整nodejs实现。 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")));
前端:
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
}
}
}
}