问题描述
我正在构建一个在线游戏,它使用 Django 通道 2.1.5 进行 websockets.
I am building an online game, which uses Django channels 2.1.5 for websockets.
我能够在客户端和服务器之间建立连接,并且也只能在消费者类中在它们之间发送数据:
I am able to build the connection between the client and the server, and also able to send data between them only inside the consumer class:
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,它位于消费者类中
Now, What I wish to do, is to call the function render, -which is inside the consumer class-, from another module
我试过了:
from .. import consumer
def sendDeployments(owner, armies):
type = "renderDeployments"
message = owner + " has " + str(armies) + " to deploy"
dummyConsumer = consumer.GameConsumer()
consumer.GameConsumer.render(type, message)
但是失败了,因为我不能在课堂外使用self"参数.
But failed because I can't use the "self" parameter from outside the class.
有人能想出一种方法来实现我的目标吗?
Can anybody think of a way to achieve my goal?
Ps:这个时候我不关心同步.
Ps: I don't care about synchronization at this occasion.
推荐答案
首先你需要你的消费者实例来订阅一个组.
Firstly you need your consumer instance to subscribe to a group.
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()
...
然后,如果您在消费者之外,则需要向该群组发送一条消息,以便所有注册到该群组的消费者都能收到该消息.
Then if you are outside of your consumer you will need to send a message to that group so that all the consumers that have registered onto the group get the message.
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}
)
但是,您还需要记住在断开连接时将您的使用者从组中移除.
However, you also need to remember to remove your consumer from the group when it disconnects.
class GameConsumer(WebsocketConsumer):
....
def disconnect(self, close_code):
async_to_sync(self.group_name)('render_updates_group')
如果您想限制哪些打开的连接收到此渲染消息,您需要相应地构建您的组名.
If you want to limit which open connections get this render message you need to build your group name accordingly.
例如,如果您正在考虑某个在线游戏,那么您可能在组名称中包含一个 MATCH-ID
,该名称由同一比赛的所有连接共享.
eg if you are thinking about some online game then maybe you include a MATCH-ID
in the group name that is shared by all connections for the same match.
对此的一个很好的参考是 channels Layers 文档,但请注意请记住,在生产环境中运行它时,您需要设置一个消息传递层(通常是 Redis).
A good reference for this is the channels Layers documentation but do remember when running this in production you will need a messaging layer (normally Redis) set up.
这篇关于使用来自 Consumer 类外部的 Django Channels 发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!