Update files
This commit is contained in:
parent
c39c26b52b
commit
3074fc7566
|
|
@ -19,7 +19,9 @@ sio = socketio.AsyncServer(
|
||||||
logger=True, # Включить логирование для отладки
|
logger=True, # Включить логирование для отладки
|
||||||
engineio_logger=True, # Включить логирование Engine.IO
|
engineio_logger=True, # Включить логирование Engine.IO
|
||||||
ping_timeout=60,
|
ping_timeout=60,
|
||||||
ping_interval=25
|
ping_interval=25,
|
||||||
|
allow_upgrades=True, # Разрешить upgrade с polling на websocket
|
||||||
|
transports=['polling', 'websocket'] # Поддерживаемые транспорты
|
||||||
)
|
)
|
||||||
|
|
||||||
# Track connected moderators
|
# Track connected moderators
|
||||||
|
|
@ -38,39 +40,26 @@ def broadcast_online():
|
||||||
sio.emit('online', online_list, namespace='/mod-chat')
|
sio.emit('online', online_list, namespace='/mod-chat')
|
||||||
|
|
||||||
|
|
||||||
# Создаем класс для корневого namespace
|
# Обработчик для корневого namespace (требуется для Socket.IO handshake)
|
||||||
class RootNamespace(socketio.AsyncNamespace):
|
# В python-socketio для ASGI режима нужно использовать декоратор БЕЗ явного namespace='/'
|
||||||
"""Root namespace handler for Socket.IO handshake"""
|
# или использовать namespace=None для корневого namespace
|
||||||
async def on_connect(self, sid, environ):
|
@sio.on('connect')
|
||||||
"""Handle client connection to root namespace (Socket.IO handshake)"""
|
async def on_connect_root(sid, environ):
|
||||||
print(f"[WebSocket] 🔄 Handshake to ROOT namespace: {sid}")
|
"""Handle client connection to root namespace (Socket.IO handshake)"""
|
||||||
print(f"[WebSocket] Environ type: {type(environ)}")
|
print(f"[WebSocket] 🔄 Handshake to ROOT namespace: {sid}")
|
||||||
if environ:
|
print(f"[WebSocket] Environ type: {type(environ)}")
|
||||||
print(f"[WebSocket] Environ keys: {list(environ.keys()) if isinstance(environ, dict) else 'N/A'}")
|
if environ:
|
||||||
logger.info(f"[WebSocket] Handshake to ROOT namespace: {sid}")
|
print(f"[WebSocket] Environ keys: {list(environ.keys()) if isinstance(environ, dict) else 'N/A'}")
|
||||||
# Разрешаем подключение для handshake
|
logger.info(f"[WebSocket] Handshake to ROOT namespace: {sid}")
|
||||||
# В AsyncNamespace не нужно возвращать True явно, но можно
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def on_disconnect(self, sid):
|
|
||||||
"""Handle disconnection from root namespace"""
|
|
||||||
print(f"[WebSocket] Client disconnected from ROOT namespace: {sid}")
|
|
||||||
logger.info(f"[WebSocket] Client disconnected from ROOT namespace: {sid}")
|
|
||||||
|
|
||||||
# Регистрируем корневой namespace ПЕРЕД созданием ASGI app
|
|
||||||
root_ns = RootNamespace('/')
|
|
||||||
sio.register_namespace(root_ns)
|
|
||||||
print(f"[WebSocket] ✅ Корневой namespace зарегистрирован: {root_ns.namespace}")
|
|
||||||
|
|
||||||
# Также добавляем обработчик через декоратор для надежности
|
|
||||||
@sio.on('connect', namespace='/')
|
|
||||||
async def on_connect_root_decorator(sid, environ):
|
|
||||||
"""Handle client connection to root namespace (Socket.IO handshake) - декоратор"""
|
|
||||||
print(f"[WebSocket] 🔄 Handshake to ROOT namespace (decorator): {sid}")
|
|
||||||
logger.info(f"[WebSocket] Handshake to ROOT namespace (decorator): {sid}")
|
|
||||||
# Разрешаем подключение для handshake
|
# Разрешаем подключение для handshake
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@sio.on('disconnect')
|
||||||
|
async def on_disconnect_root(sid):
|
||||||
|
"""Handle disconnection from root namespace"""
|
||||||
|
print(f"[WebSocket] Client disconnected from ROOT namespace: {sid}")
|
||||||
|
logger.info(f"[WebSocket] Client disconnected from ROOT namespace: {sid}")
|
||||||
|
|
||||||
# Namespace handlers for /mod-chat
|
# Namespace handlers for /mod-chat
|
||||||
@sio.on('connect', namespace='/mod-chat')
|
@sio.on('connect', namespace='/mod-chat')
|
||||||
async def on_connect(sid, environ):
|
async def on_connect(sid, environ):
|
||||||
|
|
|
||||||
|
|
@ -653,22 +653,27 @@ export default function App() {
|
||||||
hasUsername: !!user.username,
|
hasUsername: !!user.username,
|
||||||
hasTelegramId: !!user.telegramId
|
hasTelegramId: !!user.telegramId
|
||||||
});
|
});
|
||||||
// Socket.IO подключается к /socket.io, но использует namespace /mod-chat
|
// Способ 1: Подключение с явным указанием path и namespace
|
||||||
// В production Socket.IO слушает на /socket.io, namespace указывается отдельно
|
const socketUrl = socketBase.endsWith('/socket.io')
|
||||||
const socketUrl = socketBase.endsWith('/socket.io') ? socketBase : `${socketBase}/socket.io`;
|
? socketBase.replace('/socket.io', '')
|
||||||
console.log('[Chat] Подключение к Socket.IO:', socketUrl);
|
: socketBase;
|
||||||
|
|
||||||
|
console.log('[Chat] Подключение к Socket.IO base URL:', socketUrl);
|
||||||
console.log('[Chat] Использование namespace: /mod-chat');
|
console.log('[Chat] Использование namespace: /mod-chat');
|
||||||
|
|
||||||
// Подключаемся к корневому URL, но указываем namespace в опциях
|
// Подключаемся к base URL с указанием path и namespace
|
||||||
const socket = io(socketUrl, {
|
const socket = io(socketUrl, {
|
||||||
path: '/socket.io',
|
path: '/socket.io',
|
||||||
namespace: '/mod-chat',
|
namespace: '/mod-chat',
|
||||||
transports: ['websocket', 'polling'],
|
transports: ['polling', 'websocket'], // Пробуем сначала polling, потом websocket
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
reconnectionDelay: 1000,
|
reconnectionDelay: 1000,
|
||||||
reconnectionAttempts: 5,
|
reconnectionAttempts: 10,
|
||||||
timeout: 10000,
|
timeout: 20000,
|
||||||
forceNew: false
|
forceNew: true, // Принудительно новое соединение
|
||||||
|
autoConnect: true,
|
||||||
|
upgrade: true,
|
||||||
|
rememberUpgrade: false
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('connect', () => {
|
socket.on('connect', () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue