這是一個通過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