Próbuję przypisać unikalne kolory do każdego innego klienta (przy użyciu socket.id). W mojej mapie () sparowałem (socket.id, randomcolor()), ale ta zmienna znajduje się po stronie serwera. Dowiedziałem się, że instrukcja require () nie działa po stronie klienta,

  1. dlaczego tak jest i jakie jest na to rozwiązanie? Chcę móc przekazać zmienną map() po stronie klienta, aby używała koloru przypisanego do tego socket.id i odpowiednio wyświetlała kolor.

  2. Czy jest jakiś sposób na poznanie socket.id po stronie klienta (nie sądzę, ale nie jestem pewien), w szczególności komputer użytkownika musi wiedzieć, kto wysłał wiadomość, tj. Jakie socket.id zostało użyte wysłać wiadomość, czy można to wiedzieć?

Oto moja strona serwera:

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

Oto strona klienta:

// 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: Poza tym jestem nowy w JS i Socket.io, więc proszę zasugeruj kilka dobrych praktyk dla czegokolwiek w kodzie.

1
Ahmed arif Hasan 4 kwiecień 2020, 02:41

3 odpowiedzi

Najlepsza odpowiedź

Po pierwsze, JS nie ma wbudowanej właściwości include / reference.

Nie możesz więc po prostu dołączyć innego pliku do innego pliku. Ale niektóre biblioteki osiągają to za pomocą własnych, napisanych metod itp.

JS wykonywany po stronie klienta nie może uzyskać dostępu do plików lokalnych. Chociaż możesz uzyskać dostęp do pliku online, załaduj go do dokumentu lub do obiektu. Tak więc podobną funkcjonalność można osiągnąć za pomocą skryptów innych firm.

Node.JS jest zgodny z systemem modułów CommonJS i wykorzystuje moc dostępu do lokalnego systemu plików.

O indeksie: Więc nie potrzebujesz mapy, a mapa jest bardzo podobna do standardowego obiektu, główną różnicą może być kolejność treści. Ale ponieważ wszystko, czego potrzebujesz, to obiekt słownikowy. Po prostu stwórz prosty obiekt. Następnie możesz emitować indeks kolorów, kiedy tylko chcesz.

const colorIndex = {}
colorIndex[socketID] = color

Każdy może ustawić swój kolor po stronie klienta i wysłać go na serwer, na każdym serwerze aktualizacji każdy inny klient musi zaktualizować kolor.

Klient nie może znać innych klientów, w przeciwnym razie nie byłby bezpieczny i tak nie działa. Działa bardziej tak, jakbyś do kogoś dzwonił, a serwer jest pośrednikiem, który łączy was dwoje.

Zatem utwórz obiekt, przechowuj identyfikatory gniazd, pseudonimy i inne potrzebne informacje. Przechowuj to na serwerze, w każdej wiadomości wysyłaj je wszystkie razem z wiadomością.

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

Więc prawdopodobnie masz pomysł. Jest na to wiele sposobów.

1
siniradam 4 kwiecień 2020, 02:39

RequireJS odpowiada za obsługę zależności i zapewnienie, że masz wszystko, czego potrzebujesz. Jest to biblioteka Javascript, która może działać wszędzie tam, gdzie używasz Javascript, w tym po stronie serwera i klienta. Powodem, dla którego nie działa po stronie klienta (co objawia się wyświetlanym błędem), jest to, że nie jest skonfigurowany po stronie klienta.

Możesz też przeczytać o konfigurowaniu RequireJS.

Jeśli jednak skonfigurujesz go poprawnie po stronie klienta, nadal mogą wystąpić problemy, szczególnie jeśli spróbujesz użyć po stronie klienta czegoś, co jest dostępne na serwerze. Po stronie klienta jest przeglądarka, potencjalnie bardzo daleko od serwera. Na szczęście istnieje klient API dla Socket.IO.

EDYTOWAĆ

Serwer i klient mogą udostępniać wartości na kilka sposobów:

  • WebSockets (protokół dupleksowy, który należy wybrać, jeśli jest dostępny w większości przypadków)
  • Powiadomienia push
  • AJAX
  • Ładowanie strony
  • Forever frame (to hack, którego należy unikać)
0
Lajos Arpad 4 kwiecień 2020, 00:24

Nie sądzę, abyś mógł wysłać tę mapę jako argument, ale nie możesz spróbować utworzyć tablicy tablic i wyemitować ją do zdarzenia takiego jak io.emit (kolory, tablica), a kiedy już masz ją po stronie klienta, może przekształcić się z powrotem w mapę, używając czegoś takiego jak mapa lub redukuj

0
Jeff Simon 4 kwiecień 2020, 00:15