python - Flask SocketIO 在发出调用时未正确发送事件类型
问题描述
我遇到了让我的 socket.io 客户端从我的服务器正确接收具有自定义事件类型的消息的问题。
当客户端成功连接时,我正在发出从服务器获取客户端用户 ID 的请求。在尝试在 HTTP 请求和 WebSocket 之间使用会话时遇到困难后,我切换到使用 jinja 通过模板传递用户 ID。
但是,我现在无法让客户端从服务器接收自定义类型的数据包。
控制器.py
@socketio.on('connect')
def connect():
hello = 'Hello'
emit('get_user', hello, include_self=True)
socketio.sleep(0)
return
索引.html*
<script>
const socket = io(SERVER_URL/PATH);
socket.on("get_user", function (data) {
console.log(data);
socket.emit("send_user", {{ user.id }});
</script>
服务器显示它正在“发出”一条具有正确类型的消息,但随后立即将其作为消息发送。
客户端然后只接收类型"message"
而不是类型的发送消息"get_user"
问题是:我怎样才能让发射正常工作?
任何帮助将不胜感激。谢谢!
编辑:发布代码的其余部分。
控制器.py
# Import flask dependencies
from flask import Blueprint, request, render_template, flash, g, session, redirect, url_for
from flask_socketio import send, emit
# Import the database class for the app
from app import db, socketio
# Import module models
from app.mod_auth.models import User, Socket
from app.mod_home.models import Topic
# Define blueprint for home and set the url prefix
mod_home = Blueprint("home", __name__, url_prefix='/home')
@mod_home.route('/', methods=['GET'])
def home():
print('-----route------\n%r\n-------------------' % session['user_id'])
# check if user is logged in
if (not 'user_id' in session) or (session['user_id'] == None):
return redirect(url_for('auth.signin'))
user_id = session['user_id']
# Use the user id to retreive the user's friends list
user = User.query.get(user_id)
friends = user.friends.all()
# Use the user id to retreive the chats that they belong to
# Retreive a list of the top topics show first 10
return render_template("home/homepage.html", user=user, friends=friends)
@socketio.on('connect')
def connect():
# Reply back to client that connection was successful
hello = 'Hello'
emit('get_user', hello,
include_self=True)
socketio.sleep(0)
return
@socketio.on('send_user')
def register_user(user):
print(user)
# user_id = session['user_id']
# socket_id = request.sid
#
# # Create socket entry
# socket = Socket(user_id, socket_id)
#
# # Add and Commit socket entry
# db.session.add(socket)
# db.session.commit()
主页.html
<head>
<title>Home Page</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
...
<script type="text/javascript" charset="utf-8">
$(function () {
const socket = io('http://127.0.0.1:5000/home');
socket.on("get_user", function (data) {
console.log("received connection_succeeded");
console.log(data);
socket.emit("send_user", {{ user.id }});
});
});
</script>
</body>
解决方案
问题是您混合了不同的名称空间。
当您的客户端连接时,它会请求/home
命名空间(不要将 Socket.IO 命名空间与您的 URL 前缀混淆,除了两者之外没有任何关系/home
)。每次连接命名空间时,也会连接默认命名空间/
。不幸的是,这会产生一些混乱,这就是导致您的问题的原因。
您的服务器有一个连接事件处理程序/
,但没有/home
。因为你正在处理连接上/
,所以emit()
也熄灭了/
。但是,您的客户端将只处理事件,/home
因为这是您建立连接的方式。
解决方案是在任何地方使用相同的命名空间。如果您需要我的建议,我已经看到人们在命名空间上大吃一惊,以至于这些天我更喜欢在默认命名空间上工作。因此,将您的连接 URL 更改为http://127.0.0.1:5000/
,然后我认为您会没事的。
推荐阅读
- linux - JAVA_HOME 在 Linux 中不生效
- pandas - 从 Python 中的月度数据模拟半月度数据
- java - 错误:java.lang.NoClassDefFoundError:无法初始化类 Util.HibernateUtil
- integration - 在 Talend 中跳过迭代
- php - 以正确的格式将数据从数据库获取到单选按钮
- visual-c++ - 用visual studio编译代码时arch参数是怎么用的?
- python - Bulk loading with special characters using Python
- ios - Swift 4 隐藏视图,因此 onclick 适用于其下的视图
- c# - 通过 Telnet 进行终端现场定位
- c++ - 使用 Visual Studio Shell(隔离)2015 编译