SocketIO не получает сообщение в JS
Я пытаюсь реализовать FlaskSocketIO с приложением socket.io.js для связи в реальном времени между веб-интерфейсом и сервером веб-сокетов.
Код внешнего интерфейса выглядит так:
$(document).ready(function() {
namespace = '/test';
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
socket.on('connect', function() {
socket.emit('my event', {data: 'Client connected!'});
});
socket.on('my response', function(msg) {
$('#log').append('<br>' + $('<div/>').text('Received #' + msg.count + ': ' + msg.data).html());
}); });
Код, который я использую во Flask:
@socketio.on('my event', namespace='/test')
def receive__message(message):
socketio.emit('my response', {'data': 'Backend saw "' + json.dumps(message['data']) + '" from the frontend'})
print("Received from message data:" + json.dumps(message['data']))
Со стороны FlaskSocketIO я могу получить сообщение успешно, но когда я отправляю сообщение "мой respose", я вижу сообщение, перечисленное на вкладке "Сеть" из Google Chrome, как показано ниже, но не выполняется никаких действий в соответствии с моим кодом JavaScript выше для "моего ответа" ' событие:
ÿ42["my response",{"data":"Backend saw \"{\"state\": \"Client Connected \"}\" from the frontend"}]
Сказав это, связь между интерфейсом и flasksocketsio успешно установлена, но ничего не происходит в этой части кода...
socket.on('my response', function(msg) {
$('#log').append('<br>' + $('<div/>').text('Received #' + msg.count + ': ' + msg.data).html());
});
Я пытался использовать alert (msg) или даже console.log (msg), но они ничего мне не показывают, даже если я вижу полученное сообщение... Какие-нибудь подсказки, что может быть не так? Может быть, Flask сгенерирует сообщение в неправильном формате для плагина SocketIO JS?
1 ответ
Существует два способа передачи сообщений с сервера на клиент.
Вы используете socketio.emit()
функция. Это независимая от контекста функция, которая ничего не знает об окружающей среде. В вашем примере вы не включили namespace
аргумент, поэтому emit отправляется клиенту в пространстве имен по умолчанию вместо вашего /test
Пространство имен. Если вы добавите namespace='/test'
ваш клиент получит сообщение просто отлично.
Альтернативный способ, который более удобен в этом случае, состоит в использовании контекстно-зависимой emit()
функция. Это можно использовать только из обработчика событий. Эта функция получает некоторую информацию из контекста события, например, она определяет, какое пространство имен использовалось в событии, обрабатываемом в данный момент, и по умолчанию отправляет его в то же пространство имен. Это было бы что-то вроде этого:
from flask_socketio import emit
@socketio.on('my event', namespace='/test')
def receive__message(message):
emit('my response', {'data': 'Backend saw "' + json.dumps(message['data']) + '" from the frontend'})
print("Received from message data:" + json.dumps(message['data']))
Одно важное различие между контекстно-зависимой и контекстно-независимой версиями emit
является то, что контекстно-зависимая версия будет по умолчанию отправлять обратно клиенту, который отправил исходное событие, в то время как независимый от контекста отправитель будет по умолчанию транслировать всем клиентам, так как он не знает контекста.