这是一个通过socket.io做请求/响应的方案。你可以通过简单的webSocket来完成,但你必须自己构建一些基础设施。这同样库可以在客户端和服务器中使用:
function initRequestResponseSocket(socket, requestHandler) {
var cntr = 0;
var openResponses = {};
// send a request
socket.sendRequestResponse = function(data, fn) {
// put this data in a wrapper object that contains the request id
// save the callback function for this id
var id = cntr++;
openResponses[id] = fn;
socket.emit('requestMsg', {id: id, data: data});
}
// process a response message that comes back from a request
socket.on('responseMsg', function(wrapper) {
var id = wrapper.id, fn;
if (typeof id === "number" && typeof openResponses[id] === "function") {
fn = openResponses[id];
delete openResponses[id];
fn(wrapper.data);
}
});
// process a requestMsg
socket.on('requestMsg', function(wrapper) {
if (requestHandler && wrapper.id) {
requestHandler(wrapper.data, function(responseToSend) {
socket.emit('responseMsg', {id: wrapper.id, data; responseToSend});
});
}
});
}
这是通过包装在包含值唯一ID的包装对象,每发送一个信息。然后,当另一端发送它的响应时,它包含相同的id值。然后可以将该id值与该特定消息的特定回调响应处理程序进行匹配。它可以从客户端到服务器或服务器到客户端两种方式工作。
您可以通过在每一端上的socket.io套接字连接上调用initRequestResponseSocket(socket, requestHandler)
来使用此功能。如果你想接收请求,那么你传递一个requestHandler函数,每次有请求时都会调用它。如果您只发送请求并接收响应,那么您不必在连接的那端传递requestHandler。
要发送消息,并等待响应,你这样做:
socket.sendRequestResponse(data, function(err, response) {
if (!err) {
// response is here
}
});
如果收到请求并回送应答,那么你这样做:
initRequestResponseSocket(socket, function(data, respondCallback) {
// process the data here
// send response
respondCallback(null, yourResponseData);
});
至于错误处理,你可以监视连接丢失,并且你可以在这段代码中建立一个超时,这样如果响应没有在一定的时间内到达,那么你会得到一个错误。
下面是实现一个超时不来一段时间内响应上面的代码的扩展版本:
function initRequestResponseSocket(socket, requestHandler, timeout) {
var cntr = 0;
var openResponses = {};
// send a request
socket.sendRequestResponse = function(data, fn) {
// put this data in a wrapper object that contains the request id
// save the callback function for this id
var id = cntr++;
openResponses[id] = {fn: fn};
socket.emit('requestMsg', {id: id, data: data});
if (timeout) {
openResponses[id].timer = setTimeout(function() {
delete openResponses[id];
if (fn) {
fn("timeout");
}
}, timeout);
}
}
// process a response message that comes back from a request
socket.on('responseMsg', function(wrapper) {
var id = wrapper.id, requestInfo;
if (typeof id === "number" && typeof openResponse[id] === "object") {
requestInfo = openResponses[id];
delete openResponses[id];
if (requestInfo) {
if (requestInfo.timer) {
clearTimeout(requestInfo.timer);
}
if (requestInfo.fn) {
requestInfo.fn(null, wrapper.data);
}
}
}
});
// process a requestMsg
socket.on('requestMsg', function(wrapper) {
if (requestHandler && wrapper.id) {
requestHandler(wrapper.data, function(responseToSend) {
socket.emit('responseMsg', {id: wrapper.id, data; responseToSend});
});
}
});
}
在webSocket消息传递体系结构中构建请求/响应不是微不足道的。这不是自然的要求/回应。您可能需要在每条消息和响应中使用某种消息ID,因此,当您发送消息时,您可以根据您输入的ID确定哪条消息属于该消息。 – jfriend00
所以你会说使用休息和websockets并排更容易? – user3139545
那么,http是自然的请求/响应,它很容易使用。但是,如果您正在尝试执行的操作,则无法通过HTTP从服务器到客户端执行请求/响应。如果您的请求是从客户端到服务器的,那么HTTP和REST对于这一点来说更容易。 – jfriend00