我目前想知道在这种情况下什么是最好的编程实践:
假设我已将客户端连接到我的服务器。此客户端要求服务器通过auth
事件及其用户名进行身份验证。
socket = io();
socket.emit('auth', "John");
在这种简单的情况下,服务器正在使用用户ID的auth_succeed
事件进行响应。
io.on('connection', function(socket) {
socket.on('auth', function(username) {
socket.emit('auth_succeed', id);
}
}
所以我的问题是,何时何地应该绑定客户端中auth_succeed
事件的侦听器?
我有两种方式:
在发射之前,我猜测,确保响应事件将始终得到妥善处理,但会导致一些意大利面条代码。例如:
socket = io();
socket.on('auth_succeed', function(id){
//Do some post-auth stuff here
});
socket.emit('auth', "John");
或者在发射之后,这导致更清晰的代码,但我可能会再次猜测,如果发送得足够快,可以错过这个事件。例如:
socket = io();
socket.emit('auth', "John");
socket.on('auth_succeed', function(id){
//Do some post-auth stuff here
});
您对此问题的看法是什么?
答案 0 :(得分:4)
由于来自emit的响应应该是异步的,并且客户端JS本质上是同步的,socket.on('auth_succeed'
绑定将在auth
事件的回调之前发生。
客户端将发生以下流程......
// EXECUTION SCOPE BEGINS
...
// this will send a message to the server
// the message and/or response will be sent asynchronously
socket.emit('auth', 'John');
// so your code will continue before you get anything from the server
//which means the following binding will happen before any response to the above emit
socket.on('auth_succeed', function(id){
//... handle message from server ...
});
...
// EXECUTION SCOPE ENDS
在封闭范围/功能完成后的某个时间执行'auth_succeed'事件。
您可能还想考虑打破事件处理程序......
socket.on('auth_succeed', onAuthSucceed.bind(null, socket));
socket.emit('auth', 'john');
// ... elsewhere ...
function onAuthSucceed(socket, id) {
// handle message from server
}
无论您选择先绑定还是先发射,这都会降低绑定和信号事件的噪音。
通过让函数需要它需要的任何东西,并使用事件的绑定,有问题的方法可以在一个单独的文件/模块中,更容易单独测试。
答案 1 :(得分:1)
在迁移自0.9中的socket.io docs可以很好地展示如何在1.0中验证套接字。
你的一个例子是:
您应该创建一个身份验证中间件来处理这个问题。
创建一个名为authorization.js的控制器:
/**
* Socket.io middleware that that authorizes clients
* @param {object} socket
* @param {function} next
*/
module.exports = function(socket, next) {
// do some custom auth here
var handshakeData = socket.request;
// make sure the handshake data looks good with some
// custom logic
// if doesn't you can do this:
// next(new Error('not authorized');
// else just call next
next();
}
在index.js中,只需将中间件附加到io.use
:
var authorizeSockets = require('./controllers/authorization');
io.use(authorizeSockets);
自socket_io 1.0以来,io.set
已使用io.use()
折旧。
然后,您可以通过在连接事件上发出auth_suceed
来让客户知道他们已成功授权和连接,因为新的中间件到位后,除非成功授权,否则套接字将无法连接。 / p>
io.on('connection', function(socket){
socket.emit('auth_succeed', yourPayloadHere);
});
答案 2 :(得分:0)
socket.set('authorization',function(request,callback){
// check authorization for username
// set global variable flag for valid/invalid username.
if(valid_uname){
return(null,true)
}
else{
return(null,false);
}
)};
//Now on socket.on check global variable flag.
//emit when needed.