我是websockets的新手。
我正在尝试在MeanJS应用程序中实现websocket以订阅另一个网站提供的一些实时数据,当数据返回时,我想用我的视图更新结果中的表。
我遇到了一个逻辑问题。我的实现失败了,因为它试图通过单个tcp连接发送多个响应(我相信),它因错误而死:
throw new Error('Cant set headers after they are sent.');
我理解为什么会出现这个错误,但对于WebSockets是新手并且对NodeJS来说还是新手我不知道如何以有意义的方式重构这些代码。
在我的客户端控制器中:
// Get Orderbook
$scope.getOrderbook = function() {
$http.get('exchanges/' + $stateParams.exchangeId + '/get_orderbook')
.success(function(data) {
console.log("ORDERBOOK DATA: " + data); // DEBUGGING
$scope.orderBook = data;
});
};
在我的服务器端控制器中:
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,从中接收消息,以及何时收到任何消息都会使用数据更新视图?
答案 0 :(得分:0)
在每个新传入的http请求中,您尝试打开一个新的websocket到某个站点,然后每次收到消息时您都尝试发送响应。同时,你永远不会关闭你的websocket。
当您尝试在第一个响应已发送时向同一http请求发送第二个http响应时,会发生特定错误。当您在websocket上收到第二条消息时,这将在您的代码中发生。
此外,每次收到此请求时都会打开一个新的websocket,这会使这些打开的websockets累积。
如果您真的必须使用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
}
};