Flask SocketIO Emit具有broadcast = true不会将消息发送给发件人

时间:2020-04-22 01:23:50

标签: javascript python flask flask-socketio

第一次海报在这里。我正在尝试使用Flask-SocketIO整合一个聊天室应用程序,并且很难获得一个很小但至关重要的功能。当我在服务器中调用emit方法并设置broadcast = True标志时,预期的行为是它将触发所有用户(包括发送者)在客户端的相应socket.on事件。但是,我的代码显然只对发送者以外的所有客户端都这样做。这与https://flask-socketio.readthedocs.io/en/latest/中的文档相反,该文档指出:

在启用广播选项的情况下发送消息时,所有连接到名称空间的客户端都会接收到该消息,包括发送者。不使用名称空间时,连接到全局名称空间的客户端会收到消息。

为此,我需要发送消息并为发送者和所有其他客户端触发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>

1 个答案:

答案 0 :(得分:1)

事实上,所有客户端(包括发件人)都在接收发送的消息,但是这里的问题是,提交表单后,发件人的页面就会刷新(这是表单的默认行为),从而导致丢失所有本地数据。

为了防止这种情况,您需要使用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);
    };
});