python - Django Channels - self.channel_layer.group_send 不调用函数
问题描述
我正在创建一个具有聊天/投票功能的游戏。我已经在基于 Django Web 框架的 oTree 中实现了它。聊天是使用 Django Channels 制作的,在每个游戏中,一个人都有一个与其他玩家的网络,需要投票/回答问题。
我在我的消费者中定义了一个“send_choice”函数,但是当我将它作为类型引用时,它永远不会被实例化。
路由.py
from . import consumers
from django.conf.urls import re_path
websocket_routes = [
re_path(r'ws/chat/(?P<group_pk>[0-9]+)$', consumers.ChatConsumer),
re_path(r'ws/network_voting/(?P<player_pk>[0-9]+)/(?P<group_pk>[0-9]+)$', consumers.NetworkVoting)
]
消费者.py
class NetworkVoting(AsyncJsonWebsocketConsumer):
def clean_kwargs(self):
self.player_pk = self.scope['url_route']['kwargs']['player_pk']
self.group_pk = self.scope['url_route']['kwargs']['group_pk']
async def connect(self):
self.clean_kwargs()
# Join
await self.channel_layer.group_add(
self.connection_groups(),
self.channel_name
)
await self.accept()
print("Connected to Network Socket")
async def disconnect(self, close_code):
self.clean_kwargs()
await self.channel_layer.group_discard(
self.connection_groups(),
self.channel_name
)
print("Disconnected from Network Socket")
def connection_groups(self, **kwargs):
group_name = self.get_group().get_channel_group_name()
personal_channel = self.get_player().get_personal_channel_name()
return "{}-{}".format(group_name, personal_channel)
def get_player(self):
return Player.objects.get(pk=self.player_pk)
def get_group(self):
return Group.objects.get(pk=self.group_pk)
async def receive(self, text_data):
self.clean_kwargs()
text_data_json = json.loads(text_data)
msg = text_data_json['message']
await self.channel_layer.group_send(
"network_voting",
{
"type": "send_choice",
"message": "Hello"
}
)
async def send_choice(self, event):
message = event['message']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message
}))
print("Sent message")
解决方案
要在通过组发送消息时被通道调用,您需要订阅该组。
由于您发送到network_voting
您需要订阅此。
await self.channel_layer.group_add("network_voting", self.channel_name)
当您断开连接时,您还需要取消订阅。
如果您的组名是静态的,则 Channels 提供了一种简单的方法来执行此groups
操作,您可以在实例上设置一个属性。
class NetworkVoting(AsyncJsonWebsocketConsumer):
groups = ['network_voting']
然后,频道将为您处理订阅和取消订阅。
推荐阅读
- c++ - 将整数或字符串映射到 C++ 中的数据类型
- linux - 在 WSL 中执行脚本时,如何从 cmd 执行一个命令?
- python - 类型提示元组而不是太冗长
- python - 如何按当前日期的顺序查询?
- struct - Rust 枚举可以使用在其变体之一上实现的方法吗?
- r - 在每个组上拟合一个模型并使用来自该组之外的所有行的数据对其进行评估,R
- javascript - 无法在 firestore 的 productdetail 页面上获取每家餐厅的详细信息
- azure-devops - 如何将发布工件部署到不同子网中的机器位置
- python - 统计列中连续True的个数,False时重新开始
- kubernetes - 选择节点以使用 Kubernetes 执行 Nextflow 工作流