这可能是一种反模式,但是使用promise callback
从客户端向服务器发送数据时,模拟a socket.io
的最佳方法是什么?
对于某些事件,我非常希望它表现得像普通的get请求,因此客户端将数据发送到服务器,服务器可以回复响应,然后解析或拒绝承诺。
答案 0 :(得分:6)
这就是我的所作所为。我创建了一个发出socket命令的函数,然后返回一个promise。我的一个警告是,我还没有完成这个代码,所以可能需要一些调整。它还需要Q for its promises/deferreds。
var EmitPromise = function( socket, command, data ) {
var deferred = Q.defer();
socket.emit(command, data, function( response ) {
if( typeof response === "object" ) {
if( response.success === true ) {
deferred.resolve(response.data);
} else {
if( typeof response.message === "string" ) {
deferred.reject( response.message );
} else {
deferred.reject( "The request was not successful." )
}
}
} else {
deferred.reject( "The response to your request could not be parsed." );
}
});
return deferred.promise.timeout( 30000, "The request took too long to respond." );
}
EmitPromise( socket, "getValue", "username" )
.then(
function( data ) {
console.log(data);
return EmitPromise( socket, "getValue", "anotherValue" );
}, function( message ) {
console.log(message);
}
).then(
//Chain your commands from here
);
这个处理程序最重要的部分是必须使用包含"成功"包含真值或假值的键。这是我决定在服务器端出现某种错误时提供拒绝承诺的方法。
socket.on( 'getValue', function( valueName, setValueResult ) {
var value = getValue(valueName) //Do something with value here
if( value ) {
setValueResult({
success : success,
data : value
});
} else {
setValueResult({
success : success
message : "Unable to retrieve value"
});
}
}
答案 1 :(得分:1)
嗯,你必须跟踪请求。所以我会从一个“全局”计数器开始(它不一定是全局的,它足以让它在下面定义的两个函数中可见),它将在每个请求上增加(并与它一起发出)和一个“全局”处理程序名称代码可能如下所示:
var COUNTER = 0,
HANDLERS = {};
var custom_get = function(data, clb) {
COUNTER++;
var msg = {id: COUNTER, data: data};
socket.emit("GET", JSON.stringify(msg));
HANDLERS[COUNTER] = clb;
};
socket.on("GET", function(data) {
var res = JSON.parse(data);
HANDLERS[res.id](res.data);
delete HANDLERS[res.id];
});
现在您只需要确保服务器将以相同的格式响应,即JSON
{id:X, data:Y}
并将对同一请求使用相同的ID。您可以像这样使用此代码:
custom_get("test", function(res) {
console.log(res);
});
您还可以使用该代码添加例如超时。
最后看看JSON-RPC。这是一个简单的合适协议,您可以通过WebSocket轻松实现它。
答案 2 :(得分:1)
当前的socket.io版本2.1.0允许向服务器发送回调函数:
<强>客户端强>
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
服务器强>
socket.on('ferret', (name, callback) => {
callback('woot');
});
您还可以在发出之前创建一个promise,并在客户端回调函数中解析它。