同时托管服务器侧Websocket和GUI循环

发布于 2025-02-13 18:47:17 字数 1628 浏览 3 评论 0原文

我正在尝试使用JS中的Python主机和网站客户来制作一个简单的多人LAN Catan游戏。客户端很好,但是我在托管WebSocket(使用WebSockets库)上遇到问题,并同时使用同时运行GUI循环(使用Pysimplegui)(使用Pysimplegui)线程库。这是一个(希望)最小的例子:

import asyncio
import json
import websockets
import PySimpleGUI as sg
import threading

async def gameLogicHandler(event, ws):
    <handle client input>

async def handler(websocket):
    while True:
        try:
            message = await websocket.recv()
        except websockets.ConnectionClosedOK:
            break
        await gameLogicHandler(json.loads(message), websocket)

layout = [[sg.Text('Catan Server', size=(20, 1), justification='center', font='Helvetica 20')],
          [sg.Text('Players:')],
          [sg.Multiline(size=(20, 10), key='players')]]

window = sg.Window('Catan Server', layout)

def updateGui():
    while True:
        event, values = window.read()
        window["players"].update('\n'.join([player.name for player in players])) # player object I'm using that isn't included here
        if event == sg.WIN_CLOSED or event == 'Exit':
            exit()

async def main_socket():
    async with websockets.serve(handler, "", 8001):
        await asyncio.Future()

def main():
    t = threading.Thread(target=updateGui)
    t.start()
    asyncio.run(main_socket())

if __name__ == "__main__":
    main()

我敢肯定有很多错误,我对所有这些图书馆都很陌生,并且在堆栈溢出上提出问题,所以请不要太苛刻。

但是,UpdateGui函数仅运行一次,而不是不断运行。 (如果我在其中提出打印语句,则仅在控制台中一次)。如果您有任何见解,这将非常感谢。谢谢:)

编辑:我发现该函数在行事件上暂停,值= window.read.read()出于某种原因 - 如果我在该行之后放了另一个打印件,它将无法运行直到窗户关闭。

I'm trying to make a simple multiplayer lan Catan game, using a python host and website clients in js. The clients are fine, but I'm having issue with hosting the websocket (with the websockets library) and running a gui loop (using PySimpleGUI) in parallel, at the same time, with the threading library. Here's a (hopefully) minimal example:

import asyncio
import json
import websockets
import PySimpleGUI as sg
import threading

async def gameLogicHandler(event, ws):
    <handle client input>

async def handler(websocket):
    while True:
        try:
            message = await websocket.recv()
        except websockets.ConnectionClosedOK:
            break
        await gameLogicHandler(json.loads(message), websocket)

layout = [[sg.Text('Catan Server', size=(20, 1), justification='center', font='Helvetica 20')],
          [sg.Text('Players:')],
          [sg.Multiline(size=(20, 10), key='players')]]

window = sg.Window('Catan Server', layout)

def updateGui():
    while True:
        event, values = window.read()
        window["players"].update('\n'.join([player.name for player in players])) # player object I'm using that isn't included here
        if event == sg.WIN_CLOSED or event == 'Exit':
            exit()

async def main_socket():
    async with websockets.serve(handler, "", 8001):
        await asyncio.Future()

def main():
    t = threading.Thread(target=updateGui)
    t.start()
    asyncio.run(main_socket())

if __name__ == "__main__":
    main()

I'm sure there's numerous mistakes, and I'm rather new to all of these libraries, as well as asking questions on Stack Overflow, so please don't be too harsh.

However, the updateGui function just runs once, instead of constantly. (If I put a print statement in it, it's only in the console once). If you have any insights, it's very much appreciated. Thank you :)

Edit: I have discovered that the function is pausing on the line event, values = window.read() for some reason - if I put another print after that line, it would not run until the window was closed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰つ倒转 2025-02-20 18:47:18

错误

  • 应该在主线程中运行GUI
  • event = Window.Read.Read(100,none),它应该是事件,values = Window.Read.Read(100,none),<代码>无这将是timeout_key,与sg.win_closed相同。
def updateGui():

    while True:

        event = window.read(timeout=100)

        if event == sg.WIN_CLOSED or event == 'Exit':
                break
        elif event == sg.TIMEOUT_EVENT:
            window["players"].update('\n'.join([player.name for player in players]))

    window.close()

Something wrong

  • Should run GUI in main thread
  • event = window.read(100, None), it should be event, values = window.read(100, None), None here will be the timeout_key and same as sg.WIN_CLOSED.
def updateGui():

    while True:

        event = window.read(timeout=100)

        if event == sg.WIN_CLOSED or event == 'Exit':
                break
        elif event == sg.TIMEOUT_EVENT:
            window["players"].update('\n'.join([player.name for player in players]))

    window.close()
听不够的曲调 2025-02-20 18:47:18

经过多次头痛,我已经解决了这个问题,所以也许以后可以帮助某人。

我更改了我的Updategui函数:

def updateGui():
    while True:
        event = window.read(100, None)
        if event != None:
            if event == sg.WIN_CLOSED or event == 'Exit':
                exit()
        window["players"].update('\n'.join([player.name for player in players]))

这是因为窗口。阅读方法停止直到发生事件发生 - 这不是我想要的。因此,我在功能中添加了100ms的超时,这使循环正常进展。

I have fixed this, after many headaches, so maybe this can help someone later.

I changed my updateGui function to this:

def updateGui():
    while True:
        event = window.read(100, None)
        if event != None:
            if event == sg.WIN_CLOSED or event == 'Exit':
                exit()
        window["players"].update('\n'.join([player.name for player in players]))

This is because the window.read method halts until an event happens - which is not what I want. So I added a timeout of 100ms to the function, which lets the loop progress normally.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文