首页 > 解决方案 > How to use socketio to send data to reactjs from express?

问题描述

I have a simple authentication app to instagram. After I authenticate to instagram and receive user profile I would like to send the username from server side to reactjs client side. I tried using socket IO but I can't make it work.

Client side

componentDidMount() {
        const { socket, provider } = this.props
        console.log('component did mount')

        socket.on(provider, user => { //provider is a string e.g 'instagram'
        //receives data and update state.
            this.setState({user})
        })
    }

startAuth() { //onclick function that opens up new window for auth
        const {provider} = this.props

        const width = 600, height = 600
        const left = (window.innerWidth / 2) - (width / 2)
        const top = (window.innerHeight / 2) - (height / 2)
        const url = `https://localhost:5000/${provider}`

        return window.open(url, '',       
          `toolbar=no, location=no, directories=no, status=no, menubar=no, 
          scrollbars=no, resizable=no, copyhistory=no, width=${width}, 
          height=${height}, top=${top}, left=${left}`
        )        
    }

Server side

//After successful authentication redirect here with username and provider as
//query string. Here I want to emit to my component and update component's state
app.get('/success', (req, res) => {
  var provider = req.query.provider
  var username = req.query.username
  io.emit(provider, username); //this doesn't work
  res.send('Auth to ' + provider + ' successful by ' + username)
})

What should I do in order for the emitted event in server side to get caught by the on inside componentDidMount()? I got no error messages whatsoever. I'm not even sure if the emitted event at /success got fired or not.

Socket connection works fine, I did the following code below and it works fine.

io.on('connection', (client) => {
  client.on('subscribeToTimer', (interval) => {
    console.log('client is subscribing to timer with interval', interval);
    setInterval(() => {
      client.emit('timer', new Date());
    }, interval);
  })
})

标签: node.jsreactjsexpresssocket.io

解决方案


我在一个正在从事的项目中遇到了类似的问题,我解决问题的方法是

  • 创建文件io.js
// singleton instance of socket.io that is stored here after the
// constructor function is called
let ioInstance;

module.exports = function(server) {
  const io = require("socket.io")(server);
  io.on("connection", socket => {
    console.log("made socket connection", socket.id);

    // Handle socket event
    socket.on("eventTrigger", function(data) {
      // console.log(data);
      io.sockets.emit("chat", data);
    });
  });

  // save in higher scope so it can be obtained later
  ioInstance = io;
  return io;
};

// this getIO method is designed for subsequent
// sharing of the io instance with other modules once the module has been initialized
// other modules can do: let io = require("./io.js").getIO();
module.exports.getIO = () => {
  if (!ioInstance) {
    throw new Error(
      "Must call module constructor function before you can get the IO instance"
    );
  }
  return ioInstance;
};

  • 在文件bin/www中添加以下代码
var app = require("../app");
var debug = require("debug")("express-sequelize");
var http = require("http");
var models = require("../models");

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || "3000");
app.set("port", port);
/**
 * Create HTTP server.
 */
var server = http.createServer(app);

//initialize io
require("../io")(server); 

 server.listen(port, function() {
    debug("Express server listening on port " + server.address().port);
  });
  server.on("error", onError);
server.on("listening", onListening);
  • 如果我想发送套接字数据,现在在 API 调用的路由文件中
@file app.js

app.get('/success', (req, res) => {
   const io = require("./io").getIO();
   ....
   io.sockets.emit("eventTrigger",data);
  res.send('Auth to ' + provider + ' successful by ' + username)
})

希望这种方法有助于解决您面临的问题。


推荐阅读