2017-09-08 23 views
0

我想實現一個簡單的應用程序,如鬆弛,我鍵入房間名稱,它創建一個房間的名稱,任何人都可以加入這個房間,通過在url中輸入它的名字 我試過下面的代碼,但我認爲有與URL無關,那麼有沒有什麼辦法與socket.IO做到這一點直接或我必須這樣做手工如何讓用戶通過輸入名稱來輸入特定房間int int url? socket.io

server.js:

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

app.get('/', function(req, res){ 
    res.sendFile(__dirname + '/index.html'); 
}); 

io.on('connection', function(socket){ 
    io.on('connection', function(socket){ 
    socket.join('some room'); 
    console.log("joined rom"); 
}); 
    console.log('a user connected'); 
}); 

http.listen(3000, function(){ 
    console.log('listening on *:3000'); 
}); 

客戶端:

<script> 
     var socket = io(); 
    </script> 
+0

socket.join('some room');不會創造空間。房間名稱不應該有空間。 – Ved

回答

1

你的問題是有點奇怪,因爲當你請求一個URL,它獲取的瀏覽器顯示HTML的頁面。通過獲取頁​​面不會創建socket.io連接。而且,服務器不會創建socket.io連接。

所以,如果你想讓http://localhost:3000/some_room得到一個以some_room的socket.io連接結束的頁面,那麼只有幾種方法可以實現。

首先,您需要提供頁面的Express服務器上的路由。如果some_room可以是任何東西,所以URL的路徑可以是任何東西,那麼這可能不是一個很好的設計,因爲它意味着所有可能的路由到您的服務器必須以某種方式返回完全相同的頁面,並且您可以沒有其他有意義的路由。這可能不是一個好主意或設計。

相反,你可以很容易地使這樣的:

http://localhost:3000/chat/some_room 

然後,您可以爲/chat創建一個路由。該路由可以返回一個網頁,該網頁將建立適當的socket.io連接。要做到這一點最簡單的方法是使/chat路線返回一個網頁,其中包含下面的代碼:

<script src="/socket.io/socket.io.js"></script> 
<script> 
    var socket = io(); 
    socket.on('connected', function() { 
     // get path from current URL 
     let room = window.location.pathname.slice(6); // remove leading /chat/ 
     let pos = room.indexOf('/'); 
     if (pos !== -1) { 
      room = room.slice(0, pos); 
     } 
     socket.emit("joinRoom", room); 
    }); 
</script> 

然後,在服務器上:

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

app.get('/', function(req, res){ 
    res.sendFile(__dirname + '/index.html'); 
}); 

app.get('/chat/:room', function(req, res) { 
    res.sendFile(__dirname + '/chat.html'); 
}); 

io.on('connection', function(socket){ 
    // put the client in the requested room 
    socket.on("joinRoom", function(room) { 
     // only allow certain characters in room names 
     // to prevent messing with socket.io internal rooms 
     if (!(/[^\w.]/.test(room))) { 
      socket.join(room); 
     } 
    }); 
}); 
    console.log('a user connected'); 
}); 

http.listen(3000, function(){ 
    console.log('listening on *:3000'); 
}); 

它使用一個方法,即客戶端解析它是自己的URL,並根據它在URL中找到的內容發送加入房間的請求。

還有其它的方法:

  1. 客戶端可以把房間的名稱作爲初始連接上的查詢參數,因此不會有發另一條消息,加入聊天室。這在技術上更清潔(啓動時少一條消息),但需要弄清楚如何在socket.io連接參數上發送查詢參數,以及如何訪問服務器端的查詢參數(可以實現,但不是我知道的事情) )。
  2. 服務器可以從網址中解析房間名稱,並在服務該頁面時將該房間名稱嵌入到客戶端的Javascript中。我沒有親自看到爲什麼這比僅僅讓客戶端JavaScript解析URL本身更好。
  3. 服務器可以設置一個具有所需房間名稱的cookie,當客戶端與socket.io連接時,服務器可以從隨該套接字附帶的cookie獲取房間名稱。io連接請求並自動將其添加到該房間(如果由於只有一個可能被覆蓋的cookie,可能會出現不同房間名稱的同一客戶端正在處理多個頁面時會出現問題)。
2

確保空間名稱是單個字符串。它會工作。

io.on('connection', function(socket){ 
     io.on('connection', function(socket){ 
     socket.join('some_room'); 
     console.log("joined rom"); 
    }); 
+0

它的工作原理和登錄到控制檯,但與url(localhost:3000)我正在尋找一種方式來使用url(localhost:3000/some_room)像slack.com –

+0

@shroukmansour你可以將URL轉換爲單個字符串以使其工作 – Ved