简体   繁体   中英

how to make the user enter a specific room by typing it's name int the url? socket.io

I want to implement a simple app like slack, I type a room name and it creates a room with that name and any one can join this room by typing it's name in the url I tried the code below but I think there's no relation with the URL, so is there any way to do that directly with socket.IO or I have to do that manually

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');
});

client:

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

Make sure room name is single string. It will work.

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

Your question is a bit odd because when you request a URL, it fetches a page of HTML for the browser to display. No socket.io connection is created by fetching a page. And, servers don't create socket.io connections.

So, if you want http://localhost:3000/some_room to get a page that ends up with a socket.io connection in some_room , then there are only a couple ways to get there.

First, you need a route on the Express server that serves a page. If some_room can be anything so the path of your URL can literally be anything, then that's probably not a very good design because it means that all possible routes to your server must somehow return the exact same page and you can have no other meaningful routes. That's likely not a good idea or design.

Instead, you could easily make it like this:

 http://localhost:3000/chat/some_room

Then, you can create a route for /chat . That route can return a web page that will make the appropriate socket.io connection. The simplest way to do this is to make the /chat route return a web page that contains the following code:

<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>

Then, on the server:

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');
});

This uses an approach where the client parses it's own URL and sends a request to join a room based on what it finds in the URL.

There are other approaches:

  1. The client could put the room name as a query parameter on the initial connection so it wouldn't have to send another message to join the room. This is technically cleaner (one less message at startup), but requires figuring out how you send query parameters on the socket.io connection parameter and how you access them server-side (doable, but not something I know off the top of my head).
  2. The server could parse the room name out of the URL and embed that room name into the client's Javascript when it serves the page. I didn't personally see why this is better than just have the client-side Javascript parse the URL itself.
  3. The server could set a cookie with the desired room name and when the client connected with socket.io, the server could get the room name from the cookie that came with the socket.io connection request and automatically add it to that room (this has problems if there are multiple pages in process for the same client with potentially different room names because there's only one cookie that could be getting overwritten).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM