我目前正在构建一个有两个明确用例的webapp。
目前我正在使用json消息传递websocket来实现1和2。然而,事实证明这很难,因为我需要手动编码大量的错误处理,因为客户端没有等待响应。它只是发送消息,希望它有时会得到答复。 我使用Js并在前端和后端的Clojure上做出反应。
我有两个问题。
fetch
之类的东西进行休息呼叫。更新。 目前的问题是不知道如何通过websockets构建异步发送功能可以匹配发送消息和响应消息。
答案 0 :(得分:1)
这是一个通过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});
});
}
});
}
答案 1 :(得分:0)
您的问题和设计中有一些有趣的东西,我更喜欢忽略实现细节并查看高级架构。
您声明您正在寻找一个请求数据的客户端和一个响应某些数据流的服务器。这里有两点需要注意:
正如您所知,实现自己的机制带来了陷阱,这就是HTTP具有明显优势的地方。鉴于您的问题中陈述的要求,我会选择HTTP流方法,而不是实现您自己的请求/响应机制。