Django上课笔记(七)——匹配系统的实现
也欢迎大家光临我另外项目课的其他博客:
项目地址
https://git.acwing.com/codeRokie/acapp
前置知识
思路
因为匹配过程是一个长时间等待响应的过程,如果把这个过程放在游戏服务器的”主机”上,将会及其消耗资源。因此要再创建一个主机,实现匹配功能
,匹配主机
和游戏主机间
用thrift
进行通信。
由于只有一台服务器,所以两台主机
实际上是两个进程
实现的。
流程图
实现
创建匹配服务主机
1.在项目文件夹下创建match_system/src
和match_system/thrift
2.编写接口文件match_system/thrift/match.thrift
namespace py match_service
service Match {
i32 add_player(1: i32 score, 2: string uuid, 3: string username, 4: string photo, 5: string channel_name),
}
4.由接口文件,在match_system/src
下,用thrift
官方命令,生成框架代码
thrift -r --gen <语言名> <.thrift文件的路径>
thrift -r --gen py ../thrift/match.thrift
这样,就会生成match_system/src/gen-py
文件夹,将该文件夹重命名为match_server
5.完善acapp/asgi.py
#导入django支持
import django
#启动django
django.setup()
#引入channel_layer实现匹配服务器连接主机
from channels.layers import get_channel_layer
channel_layer = get_channel_layer()
6.创建并编写match_system/src/main.py
在thrift官网python示例教程的server
基础上进行修改
7.重写game/consumers/multiplayer/index.py
中的create_player()
async def create_player(self, data):
self.room_name = None
self.uuid = data['uuid']
#-----------------------------------------------------
# Make socket
transport = TSocket.TSocket('127.0.0.1', 9090)
# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)
# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = Match.Client(protocol)
# Connect!
transport.open()
#-------------------------------以上是模板------------------------------------
def db_get_player():
return Player.objects.get(user__username=data['username'])
player = await database_sync_to_async(db_get_player)()
#client.add_player()是thrift根据接口自动生成的函数
client.add_player(player.score, data['uuid'], data['username'], data['photo'], self.channel_name)
# Close!
transport.close()
8.给match_system/src/main.py
添加执行权限,并执行
bug记录
之前的代码一直使用随机分配的房间号
不玩家放在不同房间内进行对战,房间号是先于玩家创建的。
加入匹配系统后,房间是在匹配好所有玩家后才创建的,这就使得在匹配好之前,玩家不能发送其他任何指令
未完,求点赞加速更新
呜呜想问问大佬consumers/multiplayer/index.py里group_send_event的那个函数,写keys = cache.keys(…)的时候报错显示LocMemCache object has no attribute keys咋回事呀
应该是是个语法错误吧
如果把keys = cache.keys(‘%s‘ % self.uuid)改成keys = cache.has_key(‘%s‘ % self.uuid)就可以运行,但是keys里存的就不是self.uuid了,我输出了keys结果全是false呜呜