微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 PyGame 与 PyMongo 结合使用时会冻结?

如何解决为什么 PyGame 与 PyMongo 结合使用时会冻结?

这是什么错误,我不知道该怎么做...(PyMongo)。

Traceback (most recent call last):
  File "C:/Users/aatif/Documents/Projects/Games with pygame/Space Invader/Game with DB.py",line 248,in <module>
    play()
  File "C:/Users/aatif/Documents/Projects/Games with pygame/Space Invader/Game with DB.py",line 23,in play
    c.insert_one({'score': 3})
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py",line 698,in insert_one
    self._insert(document,File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py",line 613,in _insert
    return self._insert_one(
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py",line 602,in _insert_one
    self.__database.client._retryable_write(
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py",line 1497,in _retryable_write
    with self._tmp_session(session) as s:
  File "C:\Users\aatif\AppData\Local\Programs\Python\python38-32\lib\contextlib.py",line 113,in __enter__
    return next(self.gen)
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py",line 1829,in _tmp_session
    s = self._ensure_session(session)
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py",line 1816,in _ensure_session
    return self.__start_session(True,causal_consistency=False)
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py",line 1766,in __start_session
    server_session = self._get_server_session()
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py",line 1802,in _get_server_session
    return self._topology.get_server_session()
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\topology.py",line 490,in get_server_session
    self._select_servers_loop(
  File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\topology.py",line 215,in _select_servers_loop
    raise ServerSelectionTimeoutError(
pymongo.errors.ServerSelectionTimeoutError: connection closed,connection closed,Timeout: 30s,Topology Description: <TopologyDescription id: 600999bd9735fa26e13f796f,topology_type: replicasetnoprimary,servers: [<ServerDescription ('firstproject-shard-00-00.wy4pd.mongodb.net',27017) server_type: UnkNown,rtt: None,error=AutoReconnect('connection closed')>,<ServerDescription ('firstproject-shard-00-01.wy4pd.mongodb.net',<ServerDescription ('firstproject-shard-00-02.wy4pd.mongodb.net',error=AutoReconnect('connection closed')>]>

我的服务器是离线还是我设置错误? 这是一个例子(非常简短但发生同样的问题)

import pygame
from pymongo import MongoClient
# Eisa -> Username,LolLol65 -> Password
pygame.init()
win = pygame.display.set_mode((1000,400))
run = True
cluster = MongoClient(
    'mongodb+srv://USER:PASSWORD@firstproject.wy4pd.mongodb.net/Calculator?retryWrites=true&w=majority')
db = cluster['Game']
c = db['scores']
score = 0
while run:
    score += 1
    win.fill((0,0))
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            run = False
        if e.type == pygame.KEYDOWN:
            c.insert_one({'score': score})
    pygame.display.update()

(由于评论要求我添加代码。此代码重现了相同的问题,但如果更好,我也可以添加完整代码

解决方法

您遇到的特定异常似乎与您的 mongo 连接有关。你能在 MongDB Compass 中连接到你的数据库吗?

无论如何,您当前的架构将使您的游戏循环依赖于数据库写入,这可能需要大量时间。

我创建了一个示例,该示例使用单独的线程来管理 MongoDB 连接并使用队列与主线程进行通信。此示例还包括标题栏中的帧速率,并将游戏循环限制为 60 FPS。如果您将其添加到现有脚本中,则每当发生数据库插入时,您应该会看到帧速率下降。

import time
import threading
import queue
import pygame
import pymongo

# Thread for Database storage
class MongoThread(threading.Thread):
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self.queue = queue
        self.daemon = True

    def run(self):
        t_running = True
        client = pymongo.MongoClient("mongodb+srv://<insert-your-connection-string-here>")
        db = client.test
        c = db.scores
        while t_running:
            if self.queue.empty():
                time.sleep(0.1)
                pass
            else:
                data = self.queue.get()
                if data == "exit":
                    t_running = False
                else:
                    # do something with the queud data
                    c.insert_one(data)
                    print(c.count_documents({}))  # for debugging


WIDTH,HEIGHT = 1000,400
FPS = 60

# create a queue to send commands from the main thread
q = queue.Queue()
# create and then start the thread
mongo_thread = MongoThread(q) 
mongo_thread.start()

pygame.init()
win = pygame.display.set_mode((WIDTH,HEIGHT))
clock = pygame.time.Clock()
run = True
score = 0
while run:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            run = False
            q.put("exit")
        if e.type == pygame.KEYDOWN:
            # c.insert_one({"Score": score})
            q.put({"Score": score})

    score += 1
    win.fill((0,0))
    pygame.display.update()
    pygame.display.set_caption(f"FPS: {clock.get_fps():.1f}")
    clock.tick(FPS)
pygame.quit()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。