2013-08-29 78 views
1

我剛剛設法連接到一個服務器腳本與socket.io,所以我很高興。儘管我的腳本產生了奇怪的行爲,但我並不開心:我發送一個發送給服務器腳本的按鈕,服務器測試腳本將6x消息發送回控制檯日誌。用谷歌搜索這個問題描述可以獲得有關點狀,重複連接的想法,但我不認爲就是這樣。節點+ socket.io:多個服務器發射單個客戶端發射?

總之,這裏的客戶app.js:

var commentapp={ 
    init: function(){ 
     var commentapp=this; 
     commentapp.btn_api=$('#btn_api'); 
     commentapp.btn_api.click(this.get_comment_data);   
    }, 
    get_comment_data: function(btn_event){ 
     var commentapp=this; 

     console.log('trying to connect'); 
     commentapp.socket=io.connect('http://localhost:8080'); 

     commentapp.socket.on('connect', function() { 
      commentapp.socket.emit('btn_api_call'); 
     }); //commentapp.socket.on 'connect', 

     commentapp.socket.on('serverMessage', function(content){ 
      console.log(content); 
      } 
     ); //commentapp.socket.on('serverMessage' 

    } 

}; 

$(function() { 
    commentapp.init(); 
}); 

服務器腳本如下:

var httpd = require("http").createServer(handler); 
var io=require('/Users/user/Virtualenvs/node_modules/socket.io/lib/socket.io').listen(httpd); 
var fs = require('fs'); 
var url = require("url"); 
var path = require("path"); 
var port = process.argv[2] || 8080; 

httpd.listen(parseInt(port, 10)); 

function handler (request, response) { 

    var uri = url.parse(request.url).pathname,  
    filename = path.join(process.cwd(), uri);  

    console.log(uri); 

    path.exists(filename, function(exists) { 
    if(!exists) { 
     response.writeHead(404, {"Content-Type": "text/plain"}); 
     response.write("404 Not Found\n"); 
     response.end(); 
     return; //these returns get you out of the function I think 
    } 

    if (fs.statSync(filename).isDirectory()) filename += '/index.html'; 

    fs.readFile(filename, "binary", function(err, file) {  
     if(err) {   
     response.writeHead(500, {"Content-Type": "text/plain"}); 
     response.write(err + "\n"); 
     response.end(); 
     return; 
     } 

     response.writeHead(200); 
     response.write(file, "binary"); //otherwise here's where the file gets finally served 
     response.end(); 
    }); //fs.readFile 

    }); //path.exists 

     io.sockets.on('connection',function(socket) { 
     socket.on('btn_api_call', function() { 
      socket.emit('serverMessage', 'Server heard you.'); 
      }); 

     }); 

};    

console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown"); 

上述這些問題都從https://github.com/accbel/nodejs-socketio-example和佩德羅·特謝拉的書蠶食。

所以如果我點擊按鈕來生成'btn_api_call'發送,控制檯日誌會說''服務器聽到你。'「6x。希望這是一個容易設定的新手錯誤。

感謝您的幫助!

回答

2

這可能是由於您在路由處理程序中註冊了連接。

每當有一個請求到達時,由該路由處理,代碼就會爲連接添加一個新的偵聽器。

您的客戶端可能存在類似的問題 - 每次單擊按鈕時都會連接。

將您連接偵聽的途徑外是這樣的:

function handler (request, response) { 

    var uri = url.parse(request.url).pathname,  
    filename = path.join(process.cwd(), uri);  

    console.log(uri); 

    path.exists(filename, function(exists) { 
    if(!exists) { 
     response.writeHead(404, {"Content-Type": "text/plain"}); 
     response.write("404 Not Found\n"); 
     response.end(); 
     return; //these returns get you out of the function I think 
    } 

    if (fs.statSync(filename).isDirectory()) filename += '/index.html'; 

    fs.readFile(filename, "binary", function(err, file) {  
     if(err) {   
     response.writeHead(500, {"Content-Type": "text/plain"}); 
     response.write(err + "\n"); 
     response.end(); 
     return; 
     } 

     response.writeHead(200); 
     response.write(file, "binary"); //otherwise here's where the file gets finally served 
     response.end(); 
    }); //fs.readFile 

    }); //path.exists 
}; 

io.sockets.on('connection',function(socket) { 
    socket.on('btn_api_call', function() { 
    socket.emit('serverMessage', 'Server heard you.'); 
    }); 
}); 

在客戶端移動連接的邏輯來初始化 - 是這樣的:

var commentapp={ 
    init: function(){ 
     var commentapp=this; 
     commentapp.btn_api=$('#btn_api'); 
     commentapp.btn_api.click(this.get_comment_data);   

     console.log('trying to connect'); 
     commentapp.socket=io.connect('http://localhost:8080'); 

     commentapp.socket.on('connect', function() { 
      commentapp.socket.emit('btn_api_call'); 
     }); //commentapp.socket.on 'connect', 

     commentapp.socket.on('serverMessage', function(content){ 
      console.log(content); 
      } 
     ); //commentapp.socket.on('serverMessage' 
    }, 
    get_comment_data: function(btn_event){ 
     var commentapp=this; 

     commentapp.socket.emit('btn_api_call'); 
    } 

}; 
+0

謝謝您的幫助。你完全正確地使用套接字調用的範圍。說實話,我把代碼移到了這麼多處,我不確定究竟是什麼修改了一切。有一件事我發現,可能對其他人有用的是在客戶端應用程序中:我最終這樣做:\t get_comment_data:function(){ \t \t var commentapp = this; \t \t commentapp.socket = io.connect('http:// localhost:8080'); \t \t \t console.log('trying to connect'); \t \t commentapp.socket.emit('btn_api_call'); \t}。起初我並沒有意識到一切都不需要用連接類型的回調來包裝。 – ouonomos

相關問題