欢迎访问宙启技术站
智能推送

异步WebSocketConsumer(AsyncWebsocketConsumer())在Python中的应用实践

发布时间:2023-12-27 20:39:18

在Python中使用异步WebSocketConsumer(AsyncWebsocketConsumer())可以实现实时的双向通信,适用于需要长连接的应用场景。以下是一个使用异步WebSocketConsumer的简单例子:

# my_app/consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name

        # 加入聊天室
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        # 建立连接
        await self.accept()

    async def disconnect(self, close_code):
        # 离开聊天室
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # 在聊天室中广播消息
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    async def chat_message(self, event):
        message = event['message']

        # 发送消息到WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))

在上面的例子中,我们创建了一个名为ChatConsumer的异步WebSocketConsumer类,用于处理WebSocket连接。通过connect()方法建立连接,disconnect()方法关闭连接,receive()方法接收客户端发送的消息,并通过chat_message()方法处理消息。注意到这些方法都是异步的。

接下来,我们需要创建一个路由,将该Consumer与一个URL路径绑定起来:

# my_app/routing.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]

在该例中,我们创建了一个URL路径ws/chat/<room_name>/,并将它与ChatConsumer绑定。

最后,在Django的settings.py文件中,添加Channels的设置:

# settings.py

ASGI_APPLICATION = '<your_project_name>.asgi.application'

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels.layers.InMemoryChannelLayer',
        'ROUTING': '<your_project_name>.routing.websocket_urlpatterns',
    },
}

在上述配置中,我们设置了ASGI_APPLICATION为<your_project_name>.asgi.application,并配置了CHANNEL_LAYERS,指定了使用的Channel Layer。

完成以上步骤后,你可以在前端使用WebSocket API与服务器进行通信,例如下面的JavaScript代码:

// chat.js

// 连接到聊天室
const socket = new WebSocket('ws://localhost:8000/ws/chat/room1/');

// 当连接建立时,发送消息到服务器
socket.onopen = function(e) {
  socket.send(JSON.stringify({
    'message': 'Hello, server!'
  }));
};

// 接收来自服务器的消息
socket.onmessage = function(e) {
  const data = JSON.parse(e.data);
  console.log(data.message);
};

// 当连接关闭时
socket.onclose = function(e) {
  console.log('Connection closed.');
};

在上述代码中,我们使用JavaScript的WebSocket API连接到服务器的WebSocket,当连接建立时,发送一条消息到服务器,接收来自服务器的消息并打印到控制台上,当连接关闭时,也打印一条消息到控制台。

以上是一个简单的使用异步WebSocketConsumer的例子。你可以根据自己的实际需求,进行相应的定制和扩展。