node.js - 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);
})
})
解决方案
我在一个正在从事的项目中遇到了类似的问题,我解决问题的方法是
- 创建文件
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)
})
希望这种方法有助于解决您面临的问题。
推荐阅读
- javascript - 使用 React/Gatsby 在该页面上突出显示菜单图标?
- python - 平滑数据,因此使用 matplotlib 和 FFT 数据进行绘图看起来更好(频谱)
- bash - 如何通过其他文本行作为键对文本行进行排序?
- spring-boot - @XmlElement(name = "", required = true) 不能使用 springboot 验证器
- c++ - 尝试使用包含的 Qt 类库库构建项目时出错
- python - 如何翻译字典列表介绍字典列表?
- laravel-5.8 - 如何在 laravel 中编辑图像和更新
- css - 使用粘性位置删除不需要的空间
- angular - 与模板中的异步管道组合以观察值变化时,管道运算符不起作用
- android - 在运行时更新 NavDestination 标签