【问题标题】:Is there some way of importing a variable(specifically map) from the server side onto the client side(Socket.io)?是否有某种方法可以将变量(特别是映射)从服务器端导入客户端(Socket.io)?
【发布时间】:2020-07-16 05:16:48
【问题描述】:

我正在尝试为每个不同的客户端分配唯一的颜色(通过使用 socket.id )。在我的 map() 中,我已配对 (socket.id,randomcolor()),但此变量位于服务器端。我发现 require() 语句在客户端不起作用,

  1. 为什么会这样?有什么解决方案?我希望能够将map() 变量传递给客户端,以便它使用分配给该socket.id 的颜色并相应地显示颜色。

  2. 1234563用于发送消息,有可能知道吗?

这是我的服务器端:

var express = require('express');
var app = express();
app.use(express.static('public'))
var http = require('http').createServer(app);
var io = require('socket.io')(http);


const map = new Map();



io.on('connection', function(socket) {
  console.log('connected by ' + socket.id);
  map.set(socket.id, RandomColor())
  socket.on('chat', function(data) {
    //emitting to all sockets connected
    io.emit('chat', data);
    console.log(map.entries());
  });

  socket.on('typing', function(data) {
    socket.broadcast.emit('typing', data);
  })
});



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

这里是客户端:

// import '../index';
var socket = io.connect('http://localhost:3000')

var message = document.getElementById('Message');
var handle = document.getElementById('Handle');
var btn = document.getElementById('Send');
var output = document.getElementById('Output');
var feedback = document.getElementById('Feedback');

var ids = []
console.log(server);
//emit event
btn.addEventListener('click', function() {
  socket.emit('chat', {
    message: message.value,
    handle: handle.value,
  })
})

message.addEventListener('keypress', function() {
  socket.emit('typing', handle.value)
})
messageArray = []
//listening for any message received
socket.on('chat', function(data) {
  // console.log(data);  
  feedback.innerHTML = ""
  var item = document.createElement('li')
  item.innerHTML = "<span style=\"font-family:\"cursive\";\" ;><strong>" + data.handle + ": " + data.message + "</strong></span>";
  document.getElementById('Output').appendChild(item)
})

//listening for any typing event listener
socket.on('typing', function(data) {
  feedback.innerHTML = "<p><strong>" + data + " is typing a message </strong></p>";
})

PS:另外,我是 JS 和 Socket.io 的新手,所以请对代码中的任何内容提出一些好的做法。

【问题讨论】:

    标签: javascript node.js express socket.io serverside-javascript


    【解决方案1】:

    首先,JS没有内置的include/reference属性。

    因此,您不能只是将另一个文件加入另一个文件。但是有些库通过自己的书面方法等来实现这一点。

    在客户端执行的 JS 无法访问本地文件。尽管您可以访问在线文件加载到文档或对象中。因此,可以通过 3rd 方脚本实现类似的功能。

    Node.JS 遵循 CommonJS 模块系统并使用能够访问本地文件系统的能力。

    关于索引:所以你不需要 Map 并且 Map 与标准对象非常相似,主要区别可能是内容的顺序。 但是因为你只需要一个字典对象。只需创建一个简单的对象。然后,您可以随时发出颜色索引。

    const colorIndex = {}
    colorIndex[socketID] = color
    

    每个人都可以在客户端设置他们的颜色并将其发送到服务器,在每个更新服务器上都必须更新每个其他客户端的颜色。

    客户端无法知道其他客户端,否则将不安全,并且不会那样工作。它更像是你在打电话给某人,而服务器是连接你们两个的中间人。

    因此,创建一个对象,存储套接字 ID、昵称以及您需要的任何其他信息。将其保存在服务器端,在每条消息上将它们与消息一起发送。

    const users = {}
    
    io.on('connection', function(socket) {
      users[socket.id] = {//Add new user
       color:RandomColor()
      }
    
      socket.on('chat', function(message) {
        let u = users[socket.id];//Get user from index
        let data = {//Create a message package
         user:(u.username)?u.username:"Guest", //name of the user if set
         color:u.color,//color of user
         message
        }
        io.emit('chat', data );//Send
      });
    
      socket.on('setColor', function(color) {//User can update color
        users[socket.id].color = color
      });
    
      socket.on('setname', function(name) {//User can update username
        users[socket.id].username = name
      });
    });
    

    所以你可能明白了。有很多方法可以实现。

    【讨论】:

      【解决方案2】:

      RequireJS 负责处理依赖关系并确保您拥有所需的一切。它是一个 Javascript 库,可以在您使用 Javascript 的任何地方工作,包括您的服务器和客户端。它在您的客户端上不起作用的原因(这体现在您看到的错误中)是它没有在您的客户端上配置。

      您也可以阅读configurating RequireJS

      但是,如果您在客户端正确设置它,那么可能仍然存在问题,特别是如果您尝试在客户端使用服务器上可用的东西。客户端是一个浏览器,可能离服务器很远。幸运的是,Socket.IO 有一个客户端 API。

      编辑

      服务器和客户端可以通过多种方式共享值:

      • WebSockets(一种双工协议,如果在大多数情况下可用,则应选择它)
      • 推送通知
      • AJAX
      • 页面加载
      • Forever 框架(这是一种应该避免的 hack)

      【讨论】:

        【解决方案3】:

        我认为您不能将该地图作为参数发送,但您不能尝试创建一个数组数组并将其发送到像 io.emit(colors, array) 这样的事件,并且一旦您将它放在客户端,您可以使用 map 或 reduce 之类的东西转换回地图

        【讨论】:

          猜你喜欢
          • 2015-03-16
          • 1970-01-01
          • 2012-03-30
          • 2015-05-21
          • 2015-03-25
          • 2021-10-03
          • 2020-04-26
          • 1970-01-01
          • 2020-11-11
          相关资源
          最近更新 更多