Python SocketIO: BadNamespaceError: / is not a connected namespace

Python SocketIO: BadNamespaceError: / is not a connected namespace

我正在尝试设置一个在网站上流式传输您的网络摄像头的应用程序(通过遵循 this tutorial 并进行一些修改)。尝试通过 SocketIO 进行设置时,出现错误:

socketio.exceptions.BadNamespaceError: / is not a connected namespace.

我看到有人认为这个错误是由于 emit() 函数的调用速度比 connect() 函数快。但是,我的 connect() 函数是以这样的方式完成的:

    def setup(self):
    print('[INFO] Connecting to server http://{}:{}...'.format(
        self.server_addr, self.server_port))
    sio.connect(
            'http://{}:{}'.format(self.server_addr, self.server_port),
            transports=['websocket'],
            namespaces=['/cv'])
    time.sleep(1)
    return self

我尝试改变休眠时间(以便有更多时间完成连接设置)但错误仍然存​​在,我想知道如何解决这个问题。

我的代码设置在 2 个文件中,一个是创建服务器的服务器文件,另一个是发送数据的 cv 文件。这是服务器文件:

from flask_socketio import SocketIO
from flask import Flask, render_template, request
from datetime import datetime

app = Flask(__name__)
socketio = SocketIO(app)


@app.route('/')
def index():
    """Home page."""
    return render_template('index.html')


@socketio.on('connect', namespace='/web')
def connect_web():
    print('[INFO @ {}] Web client connected: {}'.format(datetime.now(), request.sid))


@socketio.on('disconnect', namespace='/web')
def disconnect_web():
    print('[INFO @ {}] Web client disconnected: {}'.format(datetime.now(), request.sid))


@socketio.on('connect', namespace='/cv')
def connect_cv():
    print('[INFO @ {}] CV client connected: {}'.format(datetime.now(), request.sid))
    

@socketio.on('disconnect', namespace='/cv')
def disconnect_cv():
    print('[INFO @ {}] CV client disconnected: {}'.format(datetime.now(), request.sid))


@socketio.on('cv2server')
def handle_cv_message(message):
    socketio.emit('server2web', message, namespace='/web')


if __name__ == "__main__":
    print('[INFO @ {}] Starting server at http://localhost:5001'.format(datetime.now()))
    socketio.run(app=app, host='0.0.0.0', port=5001)

这是发送数据的 cv 文件:

import time
import cv2

import argparse
import socketio
import base64

sio = socketio.Client()

@sio.event
def connect():
    print('[INFO] Successfully connected to server.')


@sio.event
def connect_error():
    print('[INFO] Failed to connect to server.')


@sio.event
def disconnect():
    print('[INFO] Disconnected from server.')


class CVClient(object):
    def __init__(self, server_addr, stream_fps):
        self.server_addr = server_addr
        self.server_port = 5001
        self._stream_fps = stream_fps
        self._last_update_t = time.time()
        self._wait_t = (1/self._stream_fps)

    def setup(self):
        print('[INFO] Connecting to server http://{}:{}...'.format(
            self.server_addr, self.server_port))
        sio.connect(
                'http://{}:{}'.format(self.server_addr, self.server_port),
                transports=['websocket'],
                namespaces=['/cv'])
        time.sleep(1)
        return self

    def _convert_image_to_jpeg(self, image):
        # Encode frame as jpeg
        frame = cv2.imencode('.jpg', image)[1].tobytes()
        # Encode frame in base64 representation and remove
        # utf-8 encoding
        frame = base64.b64encode(frame).decode('utf-8')
        return "data:image/jpeg;base64,{}".format(frame)

    def send_data(self, frame):
        cur_t = time.time()
        if cur_t - self._last_update_t > self._wait_t:
            self._last_update_t = cur_t
            cv2.resize(frame, (640,480))

            sio.emit(
                    'cv2server',
                    {
                        'image': self._convert_image_to_jpeg(frame)
                    })

    def check_exit(self):
        pass

    def close(self):
        sio.disconnect()


def main(use_streamer, server_addr, stream_fps):

    cap = cv2.VideoCapture(0)

    try:
        streamer = None
        streamer = CVClient(server_addr, stream_fps).setup()

        while True:
            success, img = cap.read()
            streamer.send_data(img)
            if streamer.check_exit():
                break

    finally:
        if streamer is not None:
            streamer.close()
        print("Program Ending")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Video Streamer')
    parser.add_argument(
        '--use-streamer', action='store_true',
        help='Use the embedded streamer instead of connecting to the server.')
    parser.add_argument(
        '--server-addr', type=str, default='localhost',
        help='The IP address or hostname of the SocketIO server.')
    parser.add_argument(
        '--stream-fps', type=float, default=20.0,
        help='The rate to send frames to the server.')
    args = parser.parse_args()
    main(args.use_streamer, args.server_addr, args.stream_fps)

在此先感谢您提供的任何帮助!

您正在连接 /cv 命名空间。然后您在未连接的默认命名空间 / 上发射。更改您的 emit 以使用 /cv 命名空间,错误将消失。或者,如果您需要,也可以要求连接 / 命名空间。

另请注意,连接后等待时间不够的问题是一个错误,现已修复。当前版本在发射前不需要等待期。