Передача сокета IO в комнату не работает правильно - PullRequest
0 голосов
/ 05 января 2019

Если это неопределенный вопрос, пожалуйста, дайте мне знать, чтобы я мог уточнить. Я действительно хочу обойти этот пень.

Я прочитал несколько шпаргалок о том, как правильно транслировать сообщение в клиентскую комнату. Моя ссылка: https://github.com/socketio/socket.io/blob/master/docs/emit.md.

Чтобы описать мою проблему: На странице чата правильно отображается кнопка «Отправить», однако, как только я нажимаю «Отправить», ничего не отправляется.

Интересно то, что всякий раз, когда я не использую комнаты и просто использую пространство имен по умолчанию, я могу получать сообщения.

Есть идеи о том, что происходит? Спасибо !!

server.js

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

chat.jade

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

Home.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')

Home.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')
})

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Отсутствует это под global.rooms = 'room1';

var rooms = global.rooms

Более длинный ответ: По крайней мере, я вижу, что вы добавили "комнаты" в качестве свойства глобального объекта (IDK, где определено само "глобальное", но если оно не выдает ошибку, я предполагаю, что вы определил это выше). Хотя это свойство, переменная 'rooms', которую вы используете в качестве пространства имен, не определяется во время ее вызова, поэтому она не знает, куда отправлять сообщение.

Еще больше ответа: Кроме того, если вы намереваетесь добавить дополнительные комнаты в global.rooms, я думаю, вы можете использовать хеш-лист для их хранения, чтобы вы могли легко получить к ним доступ как global.rooms[room]. так же легко добавлять новые комнаты в список, т.е. global.rooms[room.name] = room

0 голосов
/ 02 июля 2019

Проблема в том, что вы не указали, где отображать сообщения. Как я понял, у вас нет проблем с созданием комнат, поэтому я объясню шаг за шагом, как обращаться с этим пунктом.

Согласно вашему коду это связь между сервером и клиентом для отправки сообщений

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

Первый клиент отправляет сообщение (набрав в поле ввода) на сервер, и когда сервер получает его, он должен отправить то же сообщение всем другим клиентам. как только клиенты получают это сообщение, клиенты должны выяснить, как его отобразить. Но когда сервер отправляет полученное сообщение, вы должны инициировать новое событие. давайте назовем это дисплеем. поэтому ваш код должен быть таким:

//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

socket.on('display', (data) => {
    const displayedMessage = pug.render(messageTemplate, {
        message: data.message,
    })
    $messages.insertAdjacentHTML('beforeend', displayedMessage)
})

Поскольку Джейд был переименован в мопса, я использовал мопса здесь. Поэтому я буду рендерить {message: data.message} в html в теге сценария, а затем помещать его в сообщение DOM ELEMENT $.

Я не уверен, где вы хотите визуализировать handle:handle.value Я просто покажу, как отобразить сообщение. Точно так же вы можете справиться с этим.

Теперь, что такое messageTemplate, $messages и insertAdjacentHTML ()?

создать тег div и тег script в вашем html

//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>

// chat.jade

const $messages = document.getElementById("messages");
const messageTemplate = document.getElementById("message-template").innerHTML;

Метод insertAdjacentHTML () вставляет текст в виде HTML в указанную позицию. Вы можете получить больше объяснений и примеров здесь:

https://www.w3schools.com/jsref/met_node_insertadjacenthtml.asp

код сокета io выглядит длинным и сложным, но если вы знаете логику и шаг за шагом продвигаетесь, ее легко реализовать.

0 голосов
/ 05 января 2019

Попробуйте

io.in(rooms).emit('chat', data);
...