python - Python Django:在数据库保存()上从服务器向客户端发送消息
问题描述
我想在保存模型时通知客户。我首先在 post_save 上创建了一个 django 信号。
@receiver(post_save, sender=Scooter)
async def scooter_post_update(sender, instance, created, **kwargs):
# Notify client here
接下来,我从 django-channels 创建了 AsyncConsumer 类并提供了它的路由。
// routing.py
application = ProtocolTypeRouter({
# Empty for now (http->django views is added by default)
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
path('scooters/', ScootersUpdateConsumer)
]
)
)
)
})
// consumers.py
class ScootersUpdateConsumer(AsyncConsumer):
async def websocket_connect(self, event):
print("Connected!", event)
await self.send({
"type": "websocket.accept"
})
async def send_message(self):
await self.send({
"type": "websocket.send",
'text': 'Oy, mate!'
})
async def websocket_receive(self, event):
print("Receive!", event)
async def websocket_disconnect(self, event):
print("Disconnected!", event)
现在我的问题是如何从 scooter_post_update() 方法调用 send_message() 。
解决方案
这些步骤非常简单。您必须获取通道层并发送一条消息,并将type
密钥集作为您的侦听方法名称:
import channels
from asgiref.sync import async_to_sync
@receiver(post_save, sender=Scooter)
def scooter_post_update(sender, instance, created, **kwargs):
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.send)(
{"type": "send_message", "data": data}
)
以及您想通过频道发送的任何其他内容。
请注意,您传递的所有数据都必须是可序列化的,因此您必须注意预先对所有对象进行序列化。
send
传递给方法的字典的强制性部分是type
键(如前所述),它必须包含将在使用者上调用的方法名称。
此外,您可以使用组,因此您可以向一组听众广播消息:
import channels
from asgiref.sync import async_to_sync
@receiver(post_save, sender=Scooter)
def scooter_post_update(sender, instance, created, **kwargs):
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(
"group_name", {"type": "send_message", "data": data}
)
在消费者方面:
class ScootersUpdateConsumer(AsyncConsumer):
async def websocket_connect(self, event):
await self.channel_layer.group_add("group_name", self.channel_name)
await self.send({
"type": "websocket.accept"
})
请注意,在这两种情况下,您都使用async_to_sync
从同步范围调用异步代码时应使用的包装器。
推荐阅读
- python - Python列表格式字符串,列表中包含列表项
- r - 如何在两列中排除具有特定比例 NA 的受试者
- flutter - 当我们在 ChangeNotifier 中使用 notifyListeners 时?
- prometheus - 如何映射(连接)两个指标的标签
- python - 替换数据框列的值
- jupyter-notebook - 远程 Jupyter Notebook/Jupyter Lab 在没有 ssh 隧道的情况下无法连接到内核
- python - 如何更改芹菜中的键名
- spring-batch - Spring Batch Integration 消费 RabbitMq 消息
- python - Windows 上的 Multiprocessing.pool.Pool:CPU 限制为 63?
- c - shmat() - perror 返回无效参数