是否有某种方法可以将变量(特别是映射)从服务器端导入客户端(Socket.io)?

问题描述 投票:1回答:3

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

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

  2. 或有某种方法可以知道客户端的socket.id(我不知道但不确定),特别是用户计算机必须知道谁发送了消息,即使用了什么socket.id发送消息,有可能知道吗?

这是我的服务器端:

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
3个回答
1
投票

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

因此,您不能仅将另一个文件加入另一个文件。但是某些库使用自己的书面方法等来实现此目的。

在客户端执行的JS无法访问本地文件。尽管您可能会访问在线文件,但该文件或文档还是会加载到文档中。因此,可以通过第三方脚本实现类似的功能。

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

所以您可能会明白。有很多方法可以实现。


0
投票

我不认为您可以将该映射作为参数发送,但是您不能尝试创建一个数组数组并将其发射到类似io.emit(colors,array)的事件中,一旦在客户端上将其发送出去您可以使用map或reduce之类的东西转换回地图]


0
投票

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

您也可以阅读有关configurating RequireJS的信息。

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

编辑

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

  • WebSockets(在大多数情况下,应该选择双工协议)
  • 推送通知
  • AJAX
  • 页面加载
  • 永远的框架(应该避免这种情况)
© www.soinside.com 2019 - 2024. All rights reserved.