如果这是一个模糊的问题,请告诉我,以便我指定。我真的很想解决这个问题。
我已经阅读了几本有关如何正确向客户室广播消息的备忘单。我的参考是: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')
})
答案 0 :(得分:0)
尝试
io.in(rooms).emit('chat', data);
答案 1 :(得分:0)
在global.rooms = 'room1';
下缺少此
var rooms = global.rooms
更长的答案:至少我能看到,您已经在全局对象上添加了“ rooms”作为属性(idk定义了“ global”本身,但如果没有抛出错误,我假设您在上面定义)。虽然它是一个属性,但是在调用它时未定义您用作命名空间的变量“ rooms”,因此它不知道在哪里发出消息。
更多答案:另外,如果您打算向global.rooms添加其他房间,我想您可能希望使用哈希表存储它们,以便可以以global.rooms[room]
的身份轻松访问它们,以及轻松地将新房间添加到列表中,例如global.rooms[room.name] = room
答案 2 :(得分:0)
问题是您未指定在何处呈现消息。据我了解,创建房间没有问题,因此,在此之后,我将逐步说明如何处理。
根据您的代码,这是服务器和客户端之间用于发送消息的通信
//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)
})
由于Jade已重命名为哈巴狗,所以我在这里使用哈巴狗。因此,我将在脚本标签中将{message:data.message}呈现为html,然后将其放入DOM ELEMENT $ message。
我不确定您要在哪里呈现handle:handle.value
,我只会显示如何显示消息。同样,您也可以处理。
现在messageTemplate
,$messages
和insertAdjacentHTML()是什么?
在您的html中创建div标签和脚本标签
//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
socket io代码看起来很长而且很复杂,但是如果您知道逻辑并逐步进行,那么将很容易实现它。