+-
我正在构建一个在线游戏,它使用Django频道2.1.5作为websockets。
我能够在客户端和服务器之间建立连接,并且只能在消费者类中发送它们之间的数据:
from channels.generic.websocket import WebsocketConsumer
import json
from . import controller
class GameConsumer(WebsocketConsumer):
def connect(self):
self.accept()
print("Wohooo .. Connected to client!")
self.render()
controller.startTurn()
def render(self, type="render", message=None):
self.send(controller.renderMap(type, message))
def disconnect(self, close_code):
print("WebSocket connection is lost...")
def receive(self, text_data):
text_data_json = json.loads(text_data)
controller.handleRecieved(text_data)
...
现在,我想做的是从另一个模块调用函数render,它位于使用者类中
我试过这个:
from .. import consumer
def sendDeployments(owner, armies):
type = "renderDeployments"
message = owner + " has " + str(armies) + " to deploy"
dummyConsumer = consumer.GameConsumer()
consumer.GameConsumer.render(type, message)
但失败了因为我无法使用课外的“自我”参数。
任何人都可以想办法实现我的目标吗?
Ps:我不关心此时的同步。
提前致谢。
1
投票
投票
首先,您需要您的消费者实例订阅一个组。
from asgiref.sync import async_to_sync
class GameConsumer(WebsocketConsumer):
def connect(self):
self.accept()
self.render()
async_to_sync(self.add_group)('render_updates_group')
controller.startTurn()
...
然后,如果您不在消费者中,则需要向该组发送消息,以便已注册到该组的所有消费者都能获得该消息。
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
def sendDeployments(owner, armies):
type = "renderDeployments"
message = owner + " has " + str(armies) + " to deploy"
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'render_updates_group',
{'type': 'render', 'message': message}
)
但是,您还需要记住在断开连接时从组中删除您的使用者。
class GameConsumer(WebsocketConsumer):
....
def disconnect(self, close_code):
async_to_sync(self.group_name)('render_updates_group')
如果要限制哪些打开的连接获取此呈现消息,则需要相应地构建组名。
例如,如果您正在考虑某些在线游戏,那么您可能在组名中包含MATCH-ID
,该名称由同一匹配的所有连接共享。
对此有一个很好的参考是channels Layers documentation,但要记住在生产中运行它时,您需要设置消息传递层(通常是Redis)。