我正在使用Node,Socket.IO和BDD創建一個聊天應用程序。在測試過程中的一個,我得到一個超時錯誤,指出:Socket.IO服務器沒有收到來自客戶端的消息
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
受影響的試驗
it('#must be able to receive a message', function(done)
{
chatterServer.on('chatterMessage', function(data)
{
console.log('Incoming message!');
expect(data).to.have.property('message');
expect(data.message).to.be('Hello, world!');
done();
});
console.log('Sending message!');
chatterClient.send('chatterMessage', { message: 'Hello, world!' });
console.log('Sent!');
});
我發現這個問題的原因是chatterMessage
事件不是由抓服務器。雖然我確實指定了它。
控制檯的輸出是:
Sending message!
Sent!
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
我可能做錯了什麼。我不太熟悉Node和Socket.IO,所以如果這個問題非常明顯,我很抱歉。
我環顧了谷歌搜索條件'socket.io服務器沒有從客戶端',但從我發現,沒有什麼幫助我解決我的問題到目前爲止。
但是我嘗試了this question的解決方案,但是這並沒有爲我解決它。
我使用摩卡和expect.js
完整的測試是:
var util = require('util');
var Chatter = require('../src/index');
var ChatterServer = Chatter.Server;
var ChatterClient = Chatter.Client;
var express = require('express');
var expect = require('expect.js');
var socketIO = require('socket.io');
var socketIOClient = require('socket.io-client');
var host = 'http://localhost';
var port = 8080;
describe('Chatter', function()
{
'use strict';
var chatterServer;
var chatterClient;
var server;
before(function()
{
var app = express();
server = app.listen(port);
});
beforeEach(function()
{
chatterServer = new ChatterServer(socketIO(server));
chatterClient = new ChatterClient(socketIOClient, util.format('%s:%s', host, port.toString()));
});
...
it('#must be able to receive a message', function(done)
{
chatterServer.on('chatterMessage', function(data)
{
console.log('Incoming message!');
expect(data).to.have.property('message');
expect(data.message).to.be('Hello, world!');
done();
});
console.log('Sending message!');
chatterClient.send('chatterMessage', { message: 'Hello, world!' });
console.log('Sent!');
});
});
我的客戶(ChatterClient)是:
(function()
{
'use strict';
function Client(socketIO, url)
{
this.socketIO = socketIO(url);
}
Client.prototype.send = function(event, data)
{
this.socketIO.emit(event, data);
};
Client.prototype.on = function(event, callback)
{
this.socketIO.on(event, callback);
};
if (module !== undefined && module.hasOwnProperty('exports')) {
module.exports = Client;
} else {
window.Chatter = {
Client: Client,
};
}
}());
服務器(ChatterServer)是:
(function()
{
'use strict';
function Server(socketIO)
{
this.socketIO = socketIO;
this.connectedUsers = {};
this.on('connection', (function(user)
{
var userID = user.client.id;
this.connectedUsers[userID] = user;
user.emit('chatterConnectionAcknowledged', { id: userID });
}).bind(this));
}
Server.prototype.on = function(event, handler)
{
this.socketIO.on(event, handler);
};
module.exports = Server;
}());
我剛試過這個,但問題依然存在。在第一方面,我可以理解這種變化。我以前就是這樣做的,但將它更改爲'this.on',因爲它會以相同的方式掛鉤,但使用服務器的方法。我知道我正在爲此創造一些開銷,但我認爲這不是什麼大問題。你的第二個改變,甚至在嘗試之前,我不得不不同意,因爲它會在客戶端而不是服務器(這是預期的效果)上掛鉤該事件。此外,*服務器*沒有收到事件開始。我想知道這是爲什麼。 – MisterBla
@ TheSerenin請複習這[gist](https://gist.github.com/wilsonbalderrama/9f87787a201a55d99cc6),我試圖複製你的代碼在這些文件上,希望它和你的一樣,這個例子正在工作。關於**第二方**的變化,我建議你使用原始socketio編寫你的例子而不創建抽象(ChatterServer,ChatterClient),這樣你就可以理解爲什麼我這樣做了。 – Wilson
我主要使用抽象,以便它支持依賴注入。這是(此時)主要用於客戶端,因爲在測試期間,客戶端使用socket.io-client包,而當它在網絡上時,它將使用socket.io全局對象。我審查了你的要點,對我來說,這與我正在做的事情似乎並沒有太大的差別。我在GitHub上託管代碼,在這裏找到repo:https://github.com/TheSerenin/chatter – MisterBla