Python中如何使用Django实现Socket I/O通信

有个需求是 web 使用 django 开发,然后另外研发的安卓 App 会与 web 服务器建立长久的 socket 链接,那么这个 socket 有较为成熟的开源项目吗,封装好的 socket 模块然后 django 直接 api 调用进行 I/O 操作。

初级程序员,有疑问还请留言联系

多谢各位 v2 大佬


Python中如何使用Django实现Socket I/O通信
10 回复

django-socketio


在Django里直接搞Socket I/O有点别扭,因为Django是同步的WSGI框架,原生不支持长连接。不过有几种路子能走,看你要干啥。

1. 直接用socketserverasyncio写独立服务 这是最干净的办法,把Web服务和Socket服务分开。比如用asyncio写个TCP服务器:

# socket_server.py
import asyncio

clients = set()

async def handle_client(reader, writer):
    addr = writer.get_extra_info('peername')
    clients.add(writer)
    print(f"新连接: {addr}")
    
    try:
        while True:
            data = await reader.read(100)
            if not data:
                break
            message = data.decode()
            print(f"收到 {addr}: {message}")
            
            # 广播给所有客户端
            for client in clients:
                if client != writer:
                    client.write(data)
                    await client.drain()
                    
    except Exception as e:
        print(f"连接错误 {addr}: {e}")
    finally:
        clients.remove(writer)
        writer.close()
        await writer.wait_closed()

async def main():
    server = await asyncio.start_server(handle_client, '127.0.0.1', 8888)
    async with server:
        await server.serve_forever()

if __name__ == "__main__":
    asyncio.run(main())

然后在Django里用websocket-clientrequests跟这个Socket服务通信。

2. 用Django Channels(推荐) 如果要跟Django深度集成,用Channels最合适。它支持WebSocket和自定义协议:

# consumers.py
from channels.generic.websocket import AsyncWebsocketConsumer
import json

class SocketConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()
        
    async def receive(self, text_data):
        # 处理收到的消息
        data = json.loads(text_data)
        # 你的业务逻辑...
        
        # 发送回复
        await self.send(text_data=json.dumps({
            'message': '收到数据',
            'data': data
        }))
        
    async def disconnect(self, close_code):
        pass

路由配置:

# routing.py
from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/socket/$', consumers.SocketConsumer.as_asgi()),
]

3. 用django-socketio(已过时) 这个库以前能用,但现在维护不行了,不推荐。

简单总结 要简单就分开部署,要深度集成就用Channels。

持续关注

django-channel django 官方项目

感谢,这个可以!

我是用 flask-socketio

django channels 不要太好用

django channels +1

Django channel

mark 一下

回到顶部