我是websockets的新手。
我试图实现一个websocket在一个MeanJS应用程序订阅一些实时数据,另一个网站提供,当数据返回时,我想更新一个表在我的视图与结果。
我遇到了一个逻辑问题。我的实现失败了,因为它试图在一个tcp连接上发送多个响应(我相信),它死于错误:
throw new Error('Cant set headers after they are sent.');
我理解为什么会发生这个错误,但是对于WebSockets和NodeJS来说,我不确定如何以一种有意义的方式重构这段代码。
在My Clientside Controller中:
// Get Orderbook
$scope.getOrderbook = function() {
$http.get('exchanges/' + $stateParams.exchangeId + '/get_orderbook')
.success(function(data) {
console.log("ORDERBOOK DATA: " + data); // DEBUGGING
$scope.orderBook = data;
});
};
In My Server Side Controller:
exports.getOrderbook = function(req, res, next) {
var exchange = req.exchange;
if(exchange.slug === 'somesite') {
var ws = new WebSocket('wss://www.somesite.com/realtimews');
ws.on('open', function open() {
ws.send('{"op": "subscribe", "args": "orderBook"}');
});
ws.on('message', function(message) {
var response = JSON.parse(message);
if(response.table) {
res.jsonp(response.data);
}
});
}
};
重构这段代码的最佳方法是什么,以便我可以订阅websocket,从它接收消息,并在收到任何消息时用数据更新视图?
在每个新的传入http请求上,您都试图打开一个新的websocket到某些站点,然后每次您收到消息时,您都试图发送响应。同时,你永远不会关闭你的websocket。
当第一个响应已经发送时,当您尝试向同一个http请求发送第二个http响应时,您会得到特定的错误。当你在websocket上获得第二个消息时,这将在你的代码中发生。
另外,每次你收到这个请求,你都会打开一个新的websocket,这只会使这些打开的websocket累积起来。
如果你真的需要使用websocket来获取数据,那么你需要在收到第一条消息后立即关闭websocket,或者删除与特定请求相关的事件处理程序。
有一种方法:
exports.getOrderbook = function(req, res, next) {
var exchange = req.exchange;
if(exchange.slug === 'somesite') {
var ws = new WebSocket('wss://www.somesite.com/realtimews');
ws.on('open', function open() {
ws.send('{"op": "subscribe", "args": "orderBook"}');
});
ws.on('message', function(message) {
var response = JSON.parse(message);
if(response.table) {
res.jsonp(response.data);
} else {
res.jsonp(/* some error response here */)
}
// close the websocket so we don't associate any more responses
// with this particular http request
ws.close();
});
} else {
// need to send some response here
}
};