使用 socket.io 创建房间

Posted

技术标签:

【中文标题】使用 socket.io 创建房间【英文标题】:create room using socket.io 【发布时间】:2020-01-10 04:14:56 【问题描述】:

我在这里阅读了一些关于 SO 的问题,其中一些用户询问如何 我尝试应用相同的概念,在阅读了我在部署的 heroku 节点 websocket 服务器上实现的文档后,图书馆的 .joinmethod 但我无法创建房间。如果我单击我在 UI 上创建的按钮,控制台将记录此错误:

Access to XMLHttpRequest at 'https://mysocketserver.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MqCuSYp' from origin 'https://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我也无法验证是否发送了消息。我的代码哪里出了问题?

server.js

const express = require('express');
const socketIO = require('socket.io');
const path = require('path');
const PORT = process.env.PORT || 3000;

const server = express()
  // .use(function(req, res)
  //   res.sendFile(__dirname + '/index.html');
  // )
  .listen(PORT, function()
    console.log(`Our app is running on port $ PORT `);
  );

const io = socketIO(server);

var users = ;
var rooms = [];

io.on('connection', function(socket)
  console.log(socket);
  console.log('Client connected');
  socket.on('createroom', function(room)
    rooms.push(room);
    io.join(room);
  );
  socket.on('chat message', function(msg)
  //  console.log('message: ' + msg);
    io.to(rooms.room)
    .emit('chat message', msg);
    //io.emit('chat message', msg);
  );
  socket.on('disconnect', function()
    console.log('Client disconnected');
  );
);

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <style>
      *  margin: 0; padding: 0; box-sizing: border-box; 
      body  font: 13px Helvetica, Arial; 
      form  background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; 
      form input  border: 0; padding: 10px; width: 90%; margin-right: .5%; 
      form button  width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; 
      #messages  list-style-type: none; margin: 0; padding: 0; 
      #messages li  padding: 5px 10px; 
      #messages li:nth-child(odd)  background: #eee; 
      #room  position: fixed; bottom: 94%;
    </style>
  </head>
  <body>
    <form atcion="" name="room" id="room">
      <input type="text" id="r" type="text" autocomplete="off" /><button>Join</button>
    </form>
    <ul id="messages"></ul>
    <form action="" name="message">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <!-- <script src="/socket.io/socket.io.js"></script> -->
    <script src="node_modules/socket.io-client/dist/socket.io.js"></script>
    <script>
      const socket = io('https://mysocketservice.herokuapp.com');
      $(function()

        $('form[name="room"]').submit(function(e)
          e.preventDefault();
          socket.emit('createroom', $('#r').val());
          console.log(socket);
        );

        $('form[name="message"]').submit(function(e)
          e.preventDefault(); // prevents page reloading
          socket.emit('chat message', $('#m').val());
          $('#m').val('');
          return false;
        );
        socket.on('chat message', function(msg)
          console.log(msg);
          $('#messages').append($('<li>').text(msg));
        );
    );
    </script>
  </body>
</html>

我想做的很简单,当用户插入房间名称然后单击加入按钮时,我希望创建房间并将用户添加到该房间。对于这个解决方案,我正在考虑实现一个注册或登录系统,但我不确定如何继续,因为我是节点开发的新手。

我也在考虑实施的一个更好的简单解决方案是创建一个随机字符串 Math.random().toString(36) 以附加到 url,然后,当用户在页面上时,获取该字符串并创建一个唯一的房间,其中所有同一网址上的用户可以聊天。我们将不胜感激找到有效解决方案的任何帮助。

【问题讨论】:

【参考方案1】:

您需要在服务器文件中启用 cors。

    首先,跨域检查是由浏览器进行的。当 javascript 向其源以外的服务器发出 XmlHttpRequest 时,如果浏览器支持 CORS,它将初始化一个 CORS 进程。否则,请求将导致错误(除非用户故意降低浏览器安全性)

    当服务器遇到 Origin HTTP 标头时,服务器将决定它是否在允许的域列表中。如果不在列表中,则请求将失败(即服务器将发送错误响应)。

npm install cors

然后像下面这样重写您的代码以启用 cors

服务器.js

const express = require('express');
const socketIO = require('socket.io');
const path = require('path');
const cors= require('cors');
const PORT = process.env.PORT || 3000;

const app = express()

app.use(cors());
  // .use(function(req, res)
  //   res.sendFile(__dirname + '/index.html');
  // )
 const server =  app.listen(PORT, function()
    console.log(`Our app is running on port $ PORT `);
  );

const io = socketIO(server);

var users = ;
var rooms = [];

io.on('connection', function(socket)
  console.log(socket);
  console.log('Client connected');
  socket.on('createroom', function(room)
    // rooms.push(room);
    socket.join(room);
  );
  socket.on('chat message', function(msg)
    //  console.log('message: ' + msg);
  );
  socket.on('disconnect', function()
    console.log('Client disconnected');
  );
);

我发现这对 how to a create room 很有帮助。

针对 Socket 实现进行了修订。

【讨论】:

感谢您的澄清,我将在我的服务器端代码中实现 CORS 支持。对于房间,我的实施是否可行,或者那里还有什么需要调整的? 我已经修改了解决方案。试试看 我忘了说。为客户端安装这个npm install socket.io-client 它已经安装了socket.io模块,我正在从那个文件夹加载客户端库。 我已经测试了提供的解决方案,但它不起作用。我也无法创建或加入房间。

以上是关于使用 socket.io 创建房间的主要内容,如果未能解决你的问题,请参考以下文章

使用 socket.io 创建房间

Node.js 和 Socket.io 创建房间

如何使用 nestjs 和 socket.io 创建房间

关于 socket.io 中的房间创建

( Socket.io ) 一个socket连接多个房间

Socket.io 中的动态房间