2014-10-14 3 views
0

Только что начал использовать CoffeeScript и ударил стену. В моем коде ниже я создаю WebSocketServer с номером в качестве первого аргумента и функцией в качестве второго аргумента. Когда код запускается, и веб-узел получает сообщение, @msgHandler теперь магически не определено. Я попытался обойти это, установив переменную handler в @msgHandler, но это тоже не определено. Если у кого-то есть идеи, я бы хотел их услышать, спасибо!Неопределенная переменная класса при определении в конструкторе

main.coffee

#Used to communicate with browser interface 
webSocketServ = new sio.WebSocketServer Sauce.Server.WebSocketPort, (data, socketId) -> 
    try 
     json = JSON.parse(data) 
     msgType = json.msgType 
    catch error 
     return 

    if (this.isAuthed(socketId)) 
     switch msgType 
      when "auth" 

      else 
       io.websocket 'TODO: ' + cmd   
    else 
     if msgType is 'auth' 
      token = json.token 

socket.coffee

class WebSocketServer 
    constructor: (@port, @msgHandler) -> 
     @webSockets = [] 
     @handlers = {} 
     @test = [] 
     @authedSockes = [] 
     @listen(@port); 
     console.log @msgHandler #msgHandler is defined here as [ Function ] 

    listen: (port) -> 
     @wsServ = engine.listen port 
     @wsServ.on 'connection', @onConnect 
     io.socket "WebServer socket started on port #{port}" 

    onConnect: (client) -> 
     io.websocket 'New connection with id of ' + client.id 

     handler = @msgHandler #@msgHandler is undefined here? 

     client.on 'message', (data) -> 
      handler data, client.id 
      io.websocket '[' + this.id + '] ' + JSON.stringify(data) 

     client.on 'close', -> 
      io.websocket '[' + this.id + '] Disconnect' 

     client.on 'error', (err) -> 
      io.websocket "IO error: " + err 

скомпилирован socket.coffee

WebSocketServer = (function() { 
    function WebSocketServer(port, msgHandler) { 
     this.port = port; 
     this.msgHandler = msgHandler; 
     this.webSockets = []; 
     this.handlers = {}; 
     this.test = []; 
     this.authedSockes = []; 
     this.listen(this.port); 
     console.log(this.msgHandler); 
    } 

    WebSocketServer.prototype.listen = function(port) { 
     this.wsServ = engine.listen(port); 
     this.wsServ.on('connection', this.onConnect); 
     return io.socket("WebServer socket started on port " + port); 
    }; 

    WebSocketServer.prototype.onConnect = function(client) { 
     var handler; 
     io.websocket('New connection with id of ' + client.id); 
     handler = this.msgHandler; 
     client.on('message', function(data) { 
     handler(data, client.id); 
     return io.websocket('[' + this.id + '] ' + JSON.stringify(data)); 
     }); 
     client.on('close', function() { 
     return io.websocket('[' + this.id + '] Disconnect'); 
     }); 
     return client.on('error', function(err) { 
     return io.websocket("IO error: " + err); 
     }); 
    }; 

    WebSocketServer.prototype.isAuthed = function(socketId) { 
     return __indexOf.call(this.authedSockets, user) >= 0; 
    }; 

    WebSocketServer.prototype.authSocket = function(socketId) { 
     this.authedSockets.push(socketId); 
     return io.websocket('Authed socket with ID of ' + socketId); 
    }; 

    WebSocketServer.prototype.deauthSocket = function(socketId) { 
     return this.authedSockets = this.authedSockets.filter(function(word) { 
     return word !== socketId; 
     }); 
    }; 

    return WebSocketServer; 

    })(); 
+0

Ха-ха, я ограничен этим моментом - заброшенный проект с открытым исходным кодом, который я модифицирую, использует его ... @LeonardoVotocelli –

+2

смешно, что это «заброшенный проект» - удачный попутчик-путешественник – culturalanomoly

+0

, если вы запишете 'this 'внутри' onConnect', действительно ли это относится к экземпляру класса? – Mathletics

ответ

3

Это не неопределенная переменная класса, вы имеете в виду, что вы не можете получить доступ к свойство экземпляра. Это вызвано общим this context issue in callbacks - вы не можете просто передать метод и ожидать, что он узнает экземпляр.

К счастью, это может быть тривиальным фиксируется в CS с использованием fat arrow syntax для определения метода и других обратных вызовов:

onConnect: (client) => 
#      ^^ 
     io.websocket 'New connection with id of ' + client.id 

     handler = @msgHandler # @ is now the expected instance 

     client.on 'message', (data) => 
#         ^^ 
      handler data, client.id 
      io.websocket '[' + @id + '] ' + JSON.stringify(data) 
#       ^or did you mean to use `client.` here? 

     client.on 'close', => 
#       ^^ 
      io.websocket '[' + @id + '] Disconnect' 

     client.on 'error', (err) -> 
      io.websocket "IO error: " + err 

Другой (и, возможно, лучше) подход может позволить своему WebSocketServer класса наследует из класса двигателя, вместо того чтобы создавать вокруг него обертку. Так как все обратные вызовы обычно вызываются на экземпляре сервера, вы можете напрямую обращаться к своим свойствам, не связывая обратные вызовы.

Смежные вопросы