代码之家  ›  专栏  ›  技术社区  ›  Ken4scholars

在Django频道中创建多个通信者

  •  2
  • Ken4scholars  · 技术社区  · 6 年前

    我正在测试用django频道构建的聊天应用程序,我试图创建2个通信者来模拟2个用户,但我一直在 psycopg2.InterfaceError: connection already closed 在我正在实例化第二个通讯器的行中。以下是我的资料:

    async def test_chat(self):
        await self.set_up()
        communicator = WebsocketCommunicator(application, self.endpoint)
        await communicator.connect()
        await communicator.receive_from()
    
        communicator2 = WebsocketCommunicator(application, self.endpoint2)
        await communicator2.connect()
        await communicator2.receive_from()
    

    它只需要一个通讯器就可以正常工作,但我需要2个通讯器来正确测试它。这不可能吗?还是我错过了什么?

    这就是stacktrace的样子。

        >       communicator2 = WebsocketCommunicator(application, self.endpoint2)
    
    test_consumers.py:282: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/channels/testing/websocket.py:26: in __init__
        super().__init__(application, self.scope)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/asgiref/testing.py:17: in __init__
        self.instance = self.application(scope)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/channels/routing.py:58: in __call__
        return self.application_mapping[scope["type"]](scope)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/channels/security/websocket.py:37: in __call__
        return self.application(scope)
    ../../weout/messaging/authentication.py:40: in __call__
        user_auth_tuple = authenticator.authenticate(request)
    ../../weout/accounts/authentication.py:44: in authenticate
        self.authenticate_client(request)
    ../../weout/accounts/authentication.py:90: in authenticate_client
        client = self.client_model.objects.get(client_id=client_id, client_secret=client_secret)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/models/manager.py:82: in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/models/query.py:397: in get
        num = len(clone)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/models/query.py:254: in __len__
        self._fetch_all()
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/models/query.py:1179: in _fetch_all
        self._result_cache = list(self._iterable_class(self))
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/models/query.py:53: in __iter__
        results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/models/sql/compiler.py:1066: in execute_sql
        cursor = self.connection.cursor()
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/backends/base/base.py:255: in cursor
        return self._cursor()
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/backends/base/base.py:234: in _cursor
        return self._prepare_cursor(self.create_cursor(name))
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/utils.py:89: in __exit__
        raise dj_exc_value.with_traceback(traceback) from exc_value
    /home/kenneth/.virtualenvs/weout/lib/python3.6/site-packages/django/db/backends/base/base.py:234: in _cursor
        return self._prepare_cursor(self.create_cursor(name))
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    
    self = <django.contrib.gis.db.backends.postgis.base.DatabaseWrapper object at 0x7faa17c7eef0>
    name = None
    
        def create_cursor(self, name=None):
            if name:
                # In autocommit mode, the cursor will be used outside of a
                # transaction, hence use a holdable cursor.
                cursor = self.connection.cursor(name, scrollable=False, withhold=self.connection.autocommit)
            else:
    >           cursor = self.connection.cursor()
    E           django.db.utils.InterfaceError: connection already closed
    

    基本上,它到达了我的验证器被调用的位置,并试图进行一个DB调用。从stacktrace可以看出,它从我实例化第二个通信器的行开始。

    communicator2 = WebsocketCommunicator(application, self.endpoint2)
    

    但是,实例化第一个通讯器并不会产生这样的错误。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Ken4scholars    6 年前

    添加 transaction=True pytest.mark.django_db 夹具解决了这个问题。出于某种原因,我从来没有考虑过