Flask SocketIO Emit with broadcast=true 不向发件人发送消息
Flask SocketIO Emit with broadcast=true does not send message to sender
第一次张贴在这里。我正在尝试使用 Flask-SocketIO 组合一个聊天室应用程序,但很难让一个微小但至关重要的部分发挥作用。当我在服务器中调用 emit 方法并设置 broadcast=True 标志时,预期的行为是它会在客户端为所有用户(包括发件人)触发相应的 socket.on 事件。但是,我的代码显然只对发件人以外的所有客户这样做。这与 https://flask-socketio.readthedocs.io/en/latest/ 上的文档相反,其中指出:
When a message is sent with the broadcast option enabled, all clients connected to the namespace receive it, including the sender. When namespaces are not used, the clients connected to the global namespace receive the message.
我需要它来发送消息并为发件人和所有其他客户端触发 socket.on 事件。谁能解释我在这里做错了什么?因为它看起来像是一个基本功能,所以我一定遗漏了一些非常明显的东西。
服务器代码:
import os
import requests
from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit, join_room, leave_room
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
socketio = SocketIO(app)
channels = ['a', 'b', 'c', 'testing', 'abc', '123']
ch_msgs = {'a': ['testing', '1234', 'high five'], 'b': ['hello']}
msg_limit = 100
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('add channel')
def add(data):
new_channel = data
channels.append(new_channel)
ch_msgs[new_channel] = list()
emit('announce channel', new_channel, broadcast=True)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
Javascript:
document.addEventListener('DOMContentLoaded', () => {
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
socket.on('connect', () => {
document.querySelector('#add_channel').onclick = () => {
const new_channel = document.querySelector('#new_channel').value;
socket.emit('add channel', new_channel);
};
});
socket.on('announce channel', data => {
const li = document.createElement('li');
li.innerHTML = '#' + `${data}`;
$('#channel_list').append(li);
});
});
HTML/CSS 片段:
<h3>Chat Channels</h3>
<br>
<ul id='channel_list' style='list-style-type:none;'>
</ul>
<form class='channel'>
<input type='text' id='new_channel' placeholder='add new channel'><input type='submit' id='add_channel' value='Add'>
</form>
实际上所有客户端都在接收发送的消息,包括发件人,但这里的问题是一旦提交表单,发件人的页面就会刷新,(这是表单的默认行为)因此导致所有本地数据丢失。
为了防止这种情况,你需要使用event.preventDefault()
方法。在您的情况下,您可以像这样更改 connect
事件的事件处理程序:
socket.on('connect', () => {
document.querySelector('#add_channel').onclick = event => {
event.preventDefault();
const textinput = document.querySelector('#new_channel')
const new_channel = textinput.value;
textinput.value = ""; // Clear input after value is saved
socket.emit('add channel', new_channel);
};
});
第一次张贴在这里。我正在尝试使用 Flask-SocketIO 组合一个聊天室应用程序,但很难让一个微小但至关重要的部分发挥作用。当我在服务器中调用 emit 方法并设置 broadcast=True 标志时,预期的行为是它会在客户端为所有用户(包括发件人)触发相应的 socket.on 事件。但是,我的代码显然只对发件人以外的所有客户这样做。这与 https://flask-socketio.readthedocs.io/en/latest/ 上的文档相反,其中指出:
When a message is sent with the broadcast option enabled, all clients connected to the namespace receive it, including the sender. When namespaces are not used, the clients connected to the global namespace receive the message.
我需要它来发送消息并为发件人和所有其他客户端触发 socket.on 事件。谁能解释我在这里做错了什么?因为它看起来像是一个基本功能,所以我一定遗漏了一些非常明显的东西。
服务器代码:
import os
import requests
from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit, join_room, leave_room
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
socketio = SocketIO(app)
channels = ['a', 'b', 'c', 'testing', 'abc', '123']
ch_msgs = {'a': ['testing', '1234', 'high five'], 'b': ['hello']}
msg_limit = 100
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('add channel')
def add(data):
new_channel = data
channels.append(new_channel)
ch_msgs[new_channel] = list()
emit('announce channel', new_channel, broadcast=True)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
Javascript:
document.addEventListener('DOMContentLoaded', () => {
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
socket.on('connect', () => {
document.querySelector('#add_channel').onclick = () => {
const new_channel = document.querySelector('#new_channel').value;
socket.emit('add channel', new_channel);
};
});
socket.on('announce channel', data => {
const li = document.createElement('li');
li.innerHTML = '#' + `${data}`;
$('#channel_list').append(li);
});
});
HTML/CSS 片段:
<h3>Chat Channels</h3>
<br>
<ul id='channel_list' style='list-style-type:none;'>
</ul>
<form class='channel'>
<input type='text' id='new_channel' placeholder='add new channel'><input type='submit' id='add_channel' value='Add'>
</form>
实际上所有客户端都在接收发送的消息,包括发件人,但这里的问题是一旦提交表单,发件人的页面就会刷新,(这是表单的默认行为)因此导致所有本地数据丢失。
为了防止这种情况,你需要使用event.preventDefault()
方法。在您的情况下,您可以像这样更改 connect
事件的事件处理程序:
socket.on('connect', () => {
document.querySelector('#add_channel').onclick = event => {
event.preventDefault();
const textinput = document.querySelector('#new_channel')
const new_channel = textinput.value;
textinput.value = ""; // Clear input after value is saved
socket.emit('add channel', new_channel);
};
});