S'il s'agit d'une question vague, merci de me le faire savoir, afin que je puisse préciser. Je veux vraiment contourner ce problème.
J'ai lu plusieurs feuilles de triche sur la façon de diffuser correctement un message dans une salle client. Ma référence est: https://github.com/socketio/ socket.io/blob/master/docs/emit.md .
Pour décrire mon problème: La page de chat affiche correctement le bouton d'envoi, mais dès que je clique sur envoyer, rien n'est jamais envoyé.
Ce qui est intéressant, c'est que chaque fois que je n'utilise pas de salles, et que je n'utilise que l'espace de noms par défaut, je peux recevoir des messages.
Une idée de ce qui se passe? Merci !!
server.js
router.post('/available', ensureAuthenticated, (req,res,next) => { var io = res.locals['socketio'] db.collection('DefaultUser').update({_id: req.user._id}, {$set: {isAvailable: true}}); res.redirect('../chat') })
chat.jade
extends layout block content h2.page-header(style = "text-align: center;"). Home Page if (user.isTutor) b(style = "text-align: center;") form(method='post', action = '/home/available') input.btn.btn-primary(type = 'submit',name='isAvailable', value = 'Available', id = 'button4') form(method='post', action = '/home/unavailable') input.btn.btn-primary(type = 'submit',name='isUnavailable', value = 'Unavailable', id = 'button5') script(src="/socket.io/socket.io.js") script. var btn = document.getElementById('button4') //var space = '#{user.room}' var socket = io.connect() btn.addEventListener('click', function() { socket.emit('subscribe', 'room1') }) div(id = 'magic') form(method='get') if (user.hasApplied) input.btn.btn-primary(type = 'submit', onclick = "javascript: form.action = '/findatutor';" name='find', value = 'Find a Tutor', class = 'middle', id = 'button7') else if (user.hasApplied == false) input.btn.btn-primary(type = 'submit', onclick = "javascript: form.action = '/findatutor';" name='find', value = 'Find a Tutor', id = 'button1') input.btn.btn-primary(type = 'submit', onclick = "javascript: form.action = '/apply';" name='become', value = 'Become a Tutor', id = 'button2')
extends layout block content h2.page-header Chat Page div(id='the-chat') div(id='chat-window') div(id='output') input(id='handle', type='text', value = user.name, style= 'width: 0px; visibility: hidden;') input(id='message', type='text', placeholder='message') button(id='send' value='Send') Send //imports the socket.io functionality on the client side for the chat.jade application script(src="/socket.io/socket.io.js") script. //variable created that mirrors connection made in the backend //matches the connection made in the server side var socket = io.connect('http://localhost:3000') //Query dom var message = document.getElementById('message') var handle = document.getElementById('handle') var btn = document.getElementById('send') var output = document.getElementById('output') //emit events btn.addEventListener('click', function() { socket.emit('chat', { message: message.value, handle: handle.value }) }) socket.on('chat', function(data) { output.innerHTML += '<p><strong>' + data.handle + ': </strong>' + data.message + '</p>'; document.getElementById('message').value = ""; })
io.on('connection', function(socket) { global.rooms = 'room1'; socket.on('subscribe', function(room) { socket.join(rooms); console.log(socket.id + 'joining room', rooms) }) socket.on('chat', function(data) { io.to(rooms).emit('chat', data); }) })
3 Réponses :
Essayez
io.in(rooms).emit('chat', data);
J'ai essayé cela, sans succès. J'ai inclus un "console.log (data)" juste après la ligne que vous venez de recommander ci-dessus et j'obtiens: {message: 'this is example text', handle: 'Bob Peterson'} @kevin
Donc, essentiellement, le message est capturé correctement, mais il n'est pas diffusé dans la salle.
Manquant ceci sous global.rooms = 'room1';
var rooms = global.rooms
Réponse plus longue: Au moins ce que je peux voir, vous avez ajouté "rooms" comme une propriété sur l'objet global (idk où «global» lui-même est défini, mais s'il ne génère pas d'erreur, je suppose que vous l'avez défini ci-dessus). Bien qu'il s'agisse d'une propriété, la variable 'rooms' que vous utilisez comme espace de noms n'est pas définie au moment où vous l'appelez, elle ne sait donc pas où émettre le message.
Encore plus de réponse: De plus, si vous avez l'intention d'ajouter des salles supplémentaires à global.rooms, je pense que vous voudrez peut-être utiliser une liste de hachage pour les stocker, afin de pouvoir y accéder facilement en tant que global.rooms [room]
, ainsi que d'ajouter facilement de nouvelles salles à la liste, c'est-à-dire global.rooms [room.name] = room
Hm vous penseriez que son serveur lèverait également une erreur indéfinie? Je me demande si les chambres sont définies à nouveau quelque part au-dessus.
Pas nécessairement. Essayez ceci dans votre console: x = ""; x.charAt (non défini); Il l'utilise comme valeur, n'accédant à aucune propriété / fonction.
Le problème est que vous n'avez pas spécifié où rendre les messages. Comme je l'ai compris, vous n'avez aucun problème à créer des salles, je vais donc vous expliquer étape par étape comment gérer après ce point.
Selon votre code, il s'agit de la communication entre le serveur et le client pour l'envoi de messages
const $messages = document.getElementById("messages"); const messageTemplate = document.getElementById("message-template").innerHTML;
Le premier client envoie le message (en tapant la zone de saisie) au serveur et lorsque le serveur le reçoit, il doit envoyer le même message à tous les autres clients. une fois que les clients reçoivent ce message, les clients doivent trouver comment l'afficher. Mais lorsque le serveur envoie le message reçu, vous devez alors lancer un nouvel événement. appelons cela affichage. votre code doit donc ressembler à ceci:
//this is where you are gonna display the message <div id="messages" class="chat__messages"></div> <!-- template messages --> <script id="message-template" type="text/html"> <div> <p>{{message}}</p> </div> </script>
Maintenant, votre client doit être à l'écoute de cet événement et doit gérer où l'afficher:
// chat.jade
socket.on('display', (data) => { const displayedMessage = pug.render(messageTemplate, { message: data.message, }) $messages.insertAdjacentHTML('beforeend', displayedMessage) })
Depuis que Jade a été renommé pug, j'ai utilisé pug ici. Je vais donc rendre {message: data.message} en html dans une balise de script, puis je l'ai placé dans DOM ELEMENT $ message.
Je ne sais pas où vous voulez rendre handle: handle.value
Je vais juste montrer comment afficher le message. de même, vous pouvez le gérer.
Maintenant que sont messageTemplate
, $ messages
et insertAdjacentHTML ()?
créer un div et une balise script dans votre html
//server.js //i always use arrow functions, but I will follow along your code socket.on('chat', function(data) { io.to(rooms).emit('display', data); })
//chat.jade
//server.js socket.on('chat', function(data) { io.to(rooms).emit('chat', data); }) //chat.jade btn.addEventListener('click', function() { socket.emit('chat', { message: message.value, handle: handle.value }) })
La méthode insertAdjacentHTML () insère un texte au format HTML, dans une position spécifiée. vous pouvez obtenir plus d'explications et d'exemples ici:
https: // www. w3schools.com/jsref/met_node_insertadjacenthtml.asp
Le code socket io semble long et compliqué, mais si vous connaissez la logique et que vous vous déplacez étape par étape, il sera facile de l'implémenter.
Y a-t-il quelqu'un dans cette pièce pour recevoir le message? Je ne vois nulle part dans chat.jade où vous émettez l'événement 'subscribe' sur le serveur afin que vous rejoignez la salle. Cet événement d'émission se situe-t-il dans une zone différente de l'application?
L'émetteur d'événement a été inclus ci-dessus dans le bouton home.jade. 2 choses devraient se produire lorsque l'utilisateur clique sur le bouton 'disponible' qui a un id = button4. Numéro un: ils doivent être redirigés vers le chat.jade et le numéro deux: ils doivent émettre un événement d'abonnement pour room1. Si cela est utile, je console.log (données) côté serveur et j'obtiens les données correctes chaque fois que je clique sur Soumettre. Le problème est que les informations ne sont pas diffusées côté client. Voici les résultats cmd: {message: 'hi', handle: 'William Sheppard'} @JamesPooley
J'ai également fourni un extrait de mon fichier home.js qui contient une demande de publication pour l'itinéraire `` disponible '' qui représente le bouton qui (1) redirigera vers la page de discussion et (2) initiera la connexion à room1 @JamesPooley
Vérifiez-moi à ce sujet. Lorsque vous naviguez de home.jade à chat.jade, ne vous déconnectez-vous pas et ne vous reconnectez-vous pas au socket? D'après ce que je sais, cela créerait une nouvelle instance d'objet de socket sur le serveur, ce qui signifie que le nouveau socket ne serait PAS abonné / dans la salle car il s'agit d'une nouvelle instance de socket. Essayez de tester en émettant l'événement d'abonnement au serveur dans le script chat.jade pour voir si cela fonctionne de cette façon. chat.jade
var socket = io.connect ('http: // localhost: 3000') socket.on ('connect', function () {socket.emit ('subscribe', 'room1')}) < / code> puis essayez le chat