图文精华

分享

请帮忙用python完成下功能

wangqiang123 发表于 2024-5-8 15:14:36 [显示全部楼层] 回帖奖励 阅读模式 0 106
你好,有下面一个demo


import asyncio
import websockets
from urllib.parse import urlparse, parse_qs

async def proxy(websocket, path):
    query = parse_qs(urlparse(path).query)
    target_url = query.get("url", [""])[0]
    if not target_url:
        await websocket.close()
        return
    try:
        async with websockets.connect(target_url) as target_ws:
            async def forward(src, dst):
                async for message in src:
                    await dst.send(message)

            await asyncio.gather(forward(websocket, target_ws), forward(target_ws, websocket))
    except Exception as e:
        print(f"Error: {e}")
        await websocket.close()

start_server = websockets.serve(proxy, "0.0.0.0", 7000)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

它的作用是启动一个ws服务,运行在10.122.122.122的设备上,当收到ws://10.122.122.122:70000?url=ws://10.133.133.133:20004/term的消息时,会获取url的参数,和ws://10.133.133.133:20004/term建立连接,并将收到的消息转发给ws://10.133.133.133:20004/term,监听响应,并转发回去,相当于一个代理,转发给url中地址,并把参数和响应做一个互相的转发。
上面是一个demo跑通了,但实际的业务场景是在一个django项目中,ws是用channels集成到django中的,我建好了一个类,
class DevicechangesProxyConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        changes_url = self.scope['query_string'].decode('utf-8')
        if 'url=' in changes_url:
            self.changes_url=changes_url.replace('url=','')

        await self.accept()


    async def disconnect(self, close_code):
        pass


    async def receive(self, text_data=None, bytes_data=None, **kwargs):
        pass


    async def websocket_disconnect(self, message):
        pass
你可以把上面demo中的功能集成到这个类中实现类似的功能吗?





没找到任何评论,期待你打破沉寂

0

主题

0

回帖

-7

积分

站内AI

积分
-7
ChatGPT 发表于 2024-5-18 16:11:20

你好,根据你提供的代码,我可以看出你已经有一个基于 Django channels 的 WebSocket 消费者类,现在需要在这个类中实现类似上面提供的 demo 的代理功能。

你可以在 receive 方法中添加类似上面 demo 中 proxy 函数的代码,来实现代理功能。具体来说,你需要解析出 text_data 中的 url 参数,然后使用 websockets.connect 方法建立到该 URL 的 WebSocket 连接,最后将收到的消息转发给该连接,并监听响应并转发回去。

你可以参考如下代码:

import asyncio
import websockets
from urllib.parse import urlparse, parse_qs

class DevicechangesProxyConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        changes_url = self.scope['query_string'].decode('utf-8')
        if 'url=' in changes_url:
            self.target_url = changes_url.replace('url=', '')

        await self.accept()

    async def disconnect(self, close_code):
        pass

    async def receive(self, text_data=None, bytes_data=None, **kwargs):
        query = parse_qs(urlparse(text_data).query)
        target_url = query.get("url", [""])[0]
        if not target_url:
            await self.close()
            return

        try:
            async with websockets.connect(target_url) as target_ws:
                async def forward(src, dst):
                    async for message in src:
                        await dst.send(message)

                await asyncio.gather(forward(self.websocket, target_ws), forward(target_ws, self.websocket))
        except Exception as e:
            print(f"Error: {e}")
            await self.close()

    async def websocket_disconnect(self, message):
        pass

希望这可以帮助到你。

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则