Я играю с 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, поэтому мне очень жаль, если этот вопрос очень очевиден.
Я искал Google с поисковыми запросами «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', так как он мог бы работать одинаково, но вместо этого использовал метод Server. Я знаю, что создаю некоторые накладные расходы, но я не думаю, что это большая проблема. Второе изменение, даже перед тем, как пытаться, я не согласен с тем, поскольку это зацепило бы это событие на клиенте, а не за сервер (что является предполагаемым эффектом). Кроме того, * сервер * не принимает событие для начала. Мне интересно, почему это так. – MisterBla
@ TheSerenin Пожалуйста, просмотрите этот [gist] (https://gist.github.com/wilsonbalderrama/9f87787a201a55d99cc6), я попытался скопировать ваш код на эти файлы, надеюсь, что он такой же, как ваш, этот пример работает. Что касается изменения на ** второй стороне **, я предлагаю вам прописать свой пример с помощью raw socketio без создания абстракции (ChatterServer, ChatterClient), чтобы вы могли понять, почему я так делаю. – Wilson
В основном я использую абстракцию, чтобы поддерживать инъекцию зависимости. Это (в данный момент) в основном используется для Клиента, так как во время тестирования клиент использует пакет socket.io-client, тогда как когда он будет в Интернете, он будет использовать глобальный объект socket.io. Я рассмотрел ваш смысл, и для меня это действительно не похоже на то, что я делаю. Я размещаю код на GitHub, найдите репо здесь: https://github.com/TheSerenin/chatter – MisterBla