Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django API GET请求中与websocket通信?_Python_Django_Websocket_Django Rest Framework - Fatal编程技术网

Python 如何在Django API GET请求中与websocket通信?

Python 如何在Django API GET请求中与websocket通信?,python,django,websocket,django-rest-framework,Python,Django,Websocket,Django Rest Framework,我试图从Django REST API方法中使用websocket和asyncio实现的websocket服务器获取响应。具有以下结构的东西: Django应用程序 显然,这使得Django GET方法返回 任何指点都将不胜感激 编辑:感谢所有回答的人!我一直在寻找一个轻量级的解决方案,因为这可能是Django应用程序需要与WS-server交互的唯一地方。我最终采用了@Joran的解决方案,但将所有内容都打包到了一个helper函数中,如下所示: class AnAPI(views.APIVi

我试图从Django REST API方法中使用websocket和asyncio实现的websocket服务器获取响应。具有以下结构的东西:

Django应用程序

显然,这使得Django GET方法返回

任何指点都将不胜感激

编辑:感谢所有回答的人!我一直在寻找一个轻量级的解决方案,因为这可能是Django应用程序需要与WS-server交互的唯一地方。我最终采用了@Joran的解决方案,但将所有内容都打包到了一个helper函数中,如下所示:

class AnAPI(views.APIView):

    def get(self, request):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        result = loop.run_until_complete(my_async_helper_function())
        return Response(...)


async def my_async_helper_function():

    try:
            timeout = 5
            try:
                ws_conn = await asyncio.wait_for(websockets.connect(WS_STRING), timeout)
            except ConnectionTimeoutError as e:
                 <.....>

            await ws_conn.send(...)
            response = await ws_conn.recv()
            await ws_conn.close()
            return ...
        except Exception as e:
            print(e)
            await ws_conn.close()
            return ...



我认为您不能将async与django响应一起使用

相反,你可以试试

import asyncio

class AnAPI(views.APIView):
    def get(self, request):
        try:
        timeout = 5
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop) 
        try:                
            ws_conn = loop.run_until_complete(websockets.connect(WS_STRING), timeout)               
        except ConnectionTimeoutError as e:
             <.....>

        loop.run_until_complete(ws_conn.send(...))
        response = loop.run_until_complete(ws_conn.recv())
        ws_conn.close()
        return Response(...)

或者,我相信它提供了一个非常容易使用的非异步接口

我不认为您可以返回异步端点,可以吗。。。只要去掉异步,我想它会工作的。。。但在WebSocket中更常见的是js客户端连接到套接字,而不是端点。。。通过像普通api一样反复连接WebSocket,您基本上失去了WebSocket的所有好处,也遭受了WebSocket的所有坏处call@JoranBeasley我之前试过,但我认为如果我想在函数中使用wait,它告诉我必须在前面使用async?不,我认为可以使用asyncio调用函数而不使用wait... 您可能需要更多的控件来检测连接的时间established@JoranBeasley是的,这是一种奇怪的情况,WS-server主要与js客户端交互,但是对于这个特定的端点,如果我能够收集一些仅在该WS-server上可用的信息,那就太好了。..loop=asyncio.new_event_loop;asyncio.set\u event\u looploop;result=loop.run_直到_完成some_async_fndjango或使用更简单的东西我很确定有一个纯python的websocket客户端软件包,它非常简单易用,谢谢老兄!更新了我的问题,采用了效果相当好的解决方案。。。老实说,我会推荐这个特定用例的其他包。。。但是有辅助功能可能没什么坏处
AssertionError: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'coroutine'>`
class AnAPI(views.APIView):

    def get(self, request):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        result = loop.run_until_complete(my_async_helper_function())
        return Response(...)


async def my_async_helper_function():

    try:
            timeout = 5
            try:
                ws_conn = await asyncio.wait_for(websockets.connect(WS_STRING), timeout)
            except ConnectionTimeoutError as e:
                 <.....>

            await ws_conn.send(...)
            response = await ws_conn.recv()
            await ws_conn.close()
            return ...
        except Exception as e:
            print(e)
            await ws_conn.close()
            return ...


import asyncio

class AnAPI(views.APIView):
    def get(self, request):
        try:
        timeout = 5
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop) 
        try:                
            ws_conn = loop.run_until_complete(websockets.connect(WS_STRING), timeout)               
        except ConnectionTimeoutError as e:
             <.....>

        loop.run_until_complete(ws_conn.send(...))
        response = loop.run_until_complete(ws_conn.recv())
        ws_conn.close()
        return Response(...)