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