使用socket.io和webpack-dev-server

时间:2017-03-05 17:58:41

标签: socket.io webpack webpack-dev-server webpack-2

快速问题的人,我正在尝试使用带有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'
  ],

但我不知道这是否可行,有谁知道如何解决这个问题?

2 个答案:

答案 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-serversocket.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
            }
        }


    }
}