2016-06-24 85 views
-1

爲了簡化,我實際上有主頁面(/)和搜索頁面(/ search),並且在搜索頁面中,我想使用socket.io向用戶發送信息,因爲我只想發送信息到一個插座,我需要io.on('連接'...)快遞內的socket.io事件

這是我的代碼,工作不正常。當我第一次去/搜索時,一切正常,但是,當我重新加載時,控制檯兩次記錄「Message#2」。

控制檯

First time 
---------- 
Message #1 
Message #2 

Second time 
---------- 
Message #1 
Message #2 

Message #1 
Message #2 
Message #2 

server.js

var express = require('express'); 
var app = express(); 
var server = require('http').createServer(app); 
var io = require('socket.io')(server); 

app.set('view engine', 'ejs'); 
app.use(express.static("public")); 

app.get('/', function(req, res) { 
    res.render('index'); 
}); 

app.get('/search', function(req, res) { 
    res.render('search'); 

    console.log('Message #1'); 

    io.on('connection', function(socket) { 

    console.log('Message #2'); // Here's the problem 

     getSearch('something', function (err, data) { 
      if (err) { 
       console.log("ERROR : ", err); 
      } else { 
       socket.emit('fetchSearch', data); 
      } 
     }); 

    }); 

}); 

server.listen('3000'); 

搜索

<html> 
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link href="../favicon.png" rel="shortcut icon" type="image/x-icon"> 

    <title>Title</title> 

    <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script> 
</head> 
<body> 
<script> 
    var socket = io(); 

    socket.on('fetchSearch', function(rows){ 
     // Rows is an array 
    }); 
</script> 
</body> 
</html> 

關於正在發生的事情或如何解決它的任何想法?

+0

好吧,讓我們看看。事件處理程序運行一次,然後兩次,然後三次,所以...您必須多次將事件處理程序綁定到事件。您的代碼似乎證實,每次調用/ search都會向連接事件添加另一個處理程序。 –

+0

你的意思是,如果你導航到/搜索,你會看到'Message#1'和'Message#2',但是如果刷新你只能看到'Message#2'? – pay

+0

我該如何改變才能工作? PD:我編輯了控制檯日誌 – bernatixer

回答

0

您的模型有點向後。有一臺服務器和潛在的許多客戶端。因此,服務器需要在啓動時爲傳入的socket.io連接建立一個監聽器。

然後,將客戶端代碼放置在要創建與服務器的socket.io連接的任何HTML頁面中。因此,HTML頁面中的代碼確定哪些頁面創建與服務器的socket.io連接,哪些不連接。這些頁面還決定從服務器偵聽哪些socket.io消息。

稍後,當您想要向特定客戶端或所有客戶端發送某些特定信息時,服務器可以使用.emit()向一個或多個當前連接的客戶端發送特定消息。

當前連接並正在偵聽該消息以及消息發送對象的客戶端將接收到該消息並可以對其執行操作。


因此,在特定的服務器代碼,移動:

io.on('connection', function(socket) {...} 

代碼的任何事件處理程序之外,在服務器初始化運行。你永遠不會想要多次運行(這是你在做什麼,因爲你在/search事件處理程序中有這個功能,所以每次點擊/search頁面時,它都會爲connection事件添加一個新的事件偵聽器。重複的事件處理程序。在服務器初始化時運行一次。

然後,請確保/search頁面包含JavaScript來創建一個socket.io連接到服務器。

然後,你就可以發送消息在將來的任何時間從您的服務器到目前加載了/search頁面的任何瀏覽器。


然後,在服務器上的/search路由處理,你必須決定你想要做什麼。由於瀏覽器尚未接收或加載/search頁面,因此您無法將數據發送到/search頁面的/search頁面的socket.io連接,所以目前還沒有頁面(以及相應的socket.io連接頁面)發送到。如果你只是想用數據填充/search的響應,那麼你應該把這些數據放在http響應本身中,而不是使用socket.io。 socket.io應該在頁面被瀏覽器加載後以及http響應完成之後進行更新。