我使用create-react-app创建的设置,并使用flux进行数据管理,应用程序需要在客户端实现socket(我为此使用socket.io)。
目前,套接字在Socket.js文件中以下列方式初始化:
import io from 'socket.io-client';
import { remoteUrl } from './constants/RemoteUrl';
import SocketWorker from './utilities/SocketWorker';
let socket = io.connect(remoteUrl + '?role=user');
socket.on('statusChange', (data) => {
return SocketWorker.receiveOrderStatusChange(data);
})
export { socket };
它确实有效,但问题是它只在加载网站时尝试连接一次服务器。当用户打开未经身份验证的站点时,它不会连接并且错过重新连接,因此未建立连接并且未收到套接字事件
我尝试创建一个类,并反复使用API重新连接对象,例如:
import io from 'socket.io-client';
import { remoteUrl } from './constants/RemoteUrl';
import SocketWorker from './utilities/SocketWorker';
function Socket() {
this.socket = io.connect(remoteUrl + '?role=user');
this.reconnect = () => {
this.socket = io.connect(remoteUrl + '?role=user');
}
}
let socket = new Socket();
socket.socket.on('statusChange', (data) => {
return SocketWorker.receiveOrderStatusChange(data);
})
export { socket };
我试图调用Socket.reconnect()方法,虽然它不起作用,也没有建立连接。任何想法或替代解决方案?
答案 0 :(得分:0)
如果有人遇到与Socket.io API相同的问题,我设法解决了这个问题:
首先,您应该将Socket封装到构造函数创建的对象中,但是不需要创建重新连接方法,因为连接已经存在(并且auth可以通过我将在下面描述的发出事件来处理):
import io from 'socket.io-client';
import { remoteUrl } from './constants/RemoteUrl';
import SocketWorker from './utilities/SocketWorker';
function Socket() {
this.socket = io.connect(remoteUrl + '?role=user');
this.socket.on('statusChange', (data) => {
return SocketWorker.receiveOrderStatusChange(data);
})
};
const socket = new Socket();
export { socket };
您可以在项目的任何位置导入套接字:
import {socket} from './Socket';
你可以致电:
socket.socket.emit('joinRoleRoom','user');
socket.socket.emit('joinIdRoom', _user._id);
在服务器端,您只需处理以下事件:
socket.on('joinRoleRoom', (role) => {
socket.join(role)
console.log('Client joined to: ' + role);
});
socket.on('joinIdRoom', (id) => {
console.log('Client joined to: ' + id);
socket.join(id)
});
套接字将根据在身份验证过程中获取的身份验证信息加入必要的会议室。
答案 1 :(得分:0)
sznrbrt最初接受的答案会起作用,但是请注意,它存在严重的安全漏洞。
如果您执行以下操作,则攻击者可以通过仅传递所需的user_id进入房间并开始接收敏感的用户信息。可能是两个人之间的私人消息。
socket.socket.emit('joinRoleRoom','user');
socket.socket.emit('joinIdRoom', user_id);
Socket.io可以选择传递extraHeaders。可以使用它来传递来自客户端的令牌。服务器将使用所需的身份验证算法来解密令牌并获得user_id
。
示例: socket.js
import io from 'socket.io-client';
import { remoteUrl } from './constants/RemoteUrl';
import SocketWorker from './utilities/SocketWorker';
const socket = io.connect(remoteUrl + '?role=user');
const socketAuth = () => {
socket.io.opts.extraHeaders = {
'x-auth-token': 'SET_TOKEN',
};
socket.io.opts.transportOptions = {
polling: {
extraHeaders: {
'x-auth-token': 'SET_TOKEN',
},
},
};
socket.io.disconnect();
socket.io.open();
};
export { socket, socketAuth };
client.js
import { socket, socketAuth } from './socket';
//After user logs in
socketAuth();
server.js,使用软件包socketio-jwt-auth
io.use(jwtAuth.authenticate({
secret: 'SECRET',
succeedWithoutToken: true
}, (payload, done) => {
if (payload && payload.id) {
return done(null, payload.id);
}
return done();
}));