2015-06-15 181 views
0

我正在使用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; 

}()); 

回答

1

你需要在兩邊改變你的代碼。

第一方,您將需要偵聽socketIO對象上的傳入套接字連接。 (見下面的強調的代碼)

 
    //.. some code 

    function Server(socketIO) 
    { 
     this.socketIO = socketIO; 
     this.connectedUsers = {}; 

     this.socketIO.on('connection', (function(user) 
     { 
      var userID = user.client.id; 

      this.connectedUsers[userID] = user; 

      user.emit('chatterConnectionAcknowledged', { id: userID }); 
     }).bind(this)); 
    } 

    //.. some code 

二側,當你添加新的事件監聽服務器上,你需要將這些事件綁定到插座,因爲他們是那些要聽的時候事件是從套接字客戶端發出的。

Server.prototype.on = function (event, handler) { 
    Object.keys(this.connectedUsers).map(function (key) { 
    this.connectedUsers[key].on(event, handler); 
    }.bind(this)); 
}; 
+0

我剛試過這個,但問題依然存在。在第一方面,我可以理解這種變化。我以前就是這樣做的,但將它更改爲'this.on',因爲它會以相同的方式掛鉤,但使用服務器的方法。我知道我正在爲此創造一些開銷,但我認爲這不是什麼大問題。你的第二個改變,甚至在嘗試之前,我不得不不同意,因爲它會在客戶端而不是服務器(這是預期的效果)上掛鉤該事件。此外,*服務器*沒有收到事件開始。我想知道這是爲什麼。 – MisterBla

+0

@ TheSerenin請複習這[gist](https://gist.github.com/wilsonbalderrama/9f87787a201a55d99cc6),我試圖複製你的代碼在這些文件上,希望它和你的一樣,這個例子正在工作。關於**第二方**的變化,我建議你使用原始socketio編寫你的例子而不創建抽象(ChatterServer,ChatterClient),這樣你就可以理解爲什麼我這樣做了。 – Wilson

+0

我主要使用抽象,以便它支持依賴注入。這是(此時)主要用於客戶端,因爲在測試期間,客戶端使用socket.io-client包,而當它在網絡上時,它將使用socket.io全局對象。我審查了你的要點,對我來說,這與我正在做的事情似乎並沒有太大的差別。我在GitHub上託管代碼,在這裏找到repo:https://github.com/TheSerenin/chatter – MisterBla

相關問題