jak zwrócić na serwer informację z trwającego wątku?

Odpowiedz Nowy wątek
2019-05-20 23:13
0

Witam,
Nie ukrywam że niewiele wiem o pythonie, a moim celem nie jest poznanie go dokładnie, tylko możliwie szybkie rozwiązanie problemu, dlatego zwracam się z prośbą o pomoc do bardziej doświadczonych (wszystko co do tej pory znalazłem w sieci rozwiązuje inne przypadki, a w moim się niestety nie sprawdza...).
W skrócie:
Mam serwer obsługujący grę w sieci lokalnej (czy jakiejkolwiek, to akurat nieistotne, komunikacja przeglądarka-serwer działa jak trzeba) - gra wymaga dwóch osób do każdej rozgrywki, gdy znajdzie się dwóch graczy tworzy im 'ich' grę - która jest obsługiwana przez oddzielny wątek (warunek konieczny).
Serwer otrzymuje zapytania z frontu i obsługuje je wywołując odpowiednie funkcje na wątku z konkretną grą.
Plik pythona z grą 'nasłuchuje' na wywołanie funkcji, wykonuje je i powinien zwrócić odpowiedź, ale tego nie robi i tego właśnie dotyczy moje pytanie:

Jak przesłać informację zwrotną z trwającego wątku (gra ciągle się toczy, więc nie kończymy wątku), na serwer (który będzie mógł zrobić z tym co trzeba, wysłać na front itp)?

W uogólnieniu tak wygląda plik z grą (czyli wątkiem):
'''
import queue
import threading

class Game(threading.Thread):
def init(...)
...

def onThread(self, function, *args, **kwargs):
    self.q.put((function, args, kwargs))

def run(self):
    while True:
        try:
            function, args, kwargs = self.q.get(timeout=self.timeout)
            function(*args, **kwargs)
        except queue.Empty:
            self.idle()

def idle(self):
    # put the code you would have put in the `run` loop here 
    pass

def do_sth(self,arg)
    ...

...
'''
Z góry dzięki za pomoc.

edytowany 1x, ostatnio: RudeNoob, 2019-05-20 23:14

Pozostało 580 znaków

2019-05-22 21:41
0

W jaki sposób komunikujesz się z klientem?

Pozostało 580 znaków

2019-05-22 21:47
0
enedil napisał(a):

W jaki sposób komunikujesz się z klientem?

Flaskiem, ale to działa dobrze. Tak samo dobrze działa wywoływanie funkcji z serwera na konkretnym wątku z grą, przekazywanie argumentów. Nie działa tylko 'zwrotka' z gry (wątku) na serwer.

Pozostało 580 znaków

2019-05-22 21:50
0

Nie działa, bo protokół HTTP (czy HTTPS) jest bezstanowy (czyli nie możesz zwrócić częściowego wyniku). Właśnie przez te problemy istnieją takie rozwiązania jak WebSockets (polecam poszukać i poczytać).

Pozostało 580 znaków

2019-05-22 21:59
0

Może coś źle wytłumaczyłem, ale u mnie gra (wątek) to tylko obsługa tego co się dzieje u klienta, a nie sam klient. Działa dobrze, chcesz to sprawdź (rozgrzebane i nie dokończone ze względu na problem z 1 posta, ale to co działa to działa): https://github.com/gincio/rochambeau

Pozostało 580 znaków

2019-05-22 22:30
1

W Pythonie domyślne argumenty są ewaluowane w momencie deklaracji funkcji:
https://stackoverflow.com/que[...]-at-definition-time-in-python

Z tego powodu, ten konstruktor jest błędny:

    def __init__(self, q = queue.Queue(), loop_time = 1.0/60, done = None): 

Kolejka tak stworzona będzie dokładnie raz (niezależnie od liczby obiektów typu Game), i wszystkie te obiekty będą z tej samej korzystać.
Nie wiem czy ten problem wynika z tego, ale być może masz teraz taką sytuację, że wątek nigdy się nie kończy, bo inne wątki piszą do tej kolejki, a Ty ciągle coś z niej wyciągasz.

Możliwe rozwiązanie: zamiast q = queue.Queue() zrób q=None (btw. brak spacji w domyślnych argumentach jest zalecany), a potem zrób typowe if not q: q = queue.Queue().

Pozostało 580 znaków

2019-05-22 22:34
0

Okej, poprawię, dzięki - faktycznie nie testowałem tego jeszcze na x wątkach, póki co staram się zrobić np drugą taką kolejkę, która będzie przechowywać wartości wynikowe funkcji zawartych w Game i będzie się ją dało odczytać z Serwera, tylko nie wiem jak to napisać, o ile to możliwe.

Pozostało 580 znaków

2019-05-22 22:41
0

Nie wiem, czy dobrze rozumiem co chcesz osiągnąć, ale wydaje mi się, że mógłbyś stworzyć kolejkę w serwerze i przesłać ją do konstruktora gry. Będziesz móc do niej pisać i czytać w serwerze. Trzymaj takie kolejki gdzieś obok miejsca gdzie są trzymane same wątki.

Pozostało 580 znaków

2019-05-22 22:55
0

Potrzebuję czegoś (kolejki?) czym mogę sobie przekazywać dane z serwera do konkretnych wątków z grami i z powrotem. Teraz (tak jak jest na gicie) mogę wysyłać z serwera do wątku gry argumenty funkcji razem z ich wywołaniem, funkcja się wykonuje i nie mam jak odczytać jej wyniku. Kiedy zapisywałem wynik do kolejki, na serwerze ta kolejka wciąż była pusta...

edytowany 3x, ostatnio: RudeNoob, 2019-05-22 23:17
Pokaż pozostałe 3 komentarze
tak już próbowałem - kolejka powstaje, przesyłam ją do wątku, tam dodaję do niej wynik wywołanej funkcji, próbuję odczytać na serwerze, a serwer mówi że kolejka jest pusta. stąd mój wniosek że brakuje mi jakiejś metody która tą kolejkę będzie synchronizować/przesyłać w drugą stronę... chyba że zwyczajnie mylę się z składni... uaktualnię gita, będzie widać. - RudeNoob 2019-05-22 23:50
Ja dostaję taki błąd: AttributeError: 'Queue' object has no attribute 'insert' (istotnie, istnieje put). - enedil 2019-05-23 00:16
mi nie wyrzucał tego, ale zorientowałem się już i poprawiłem, wciąż zwraca mi informację że kolejka jest pusta :/ - RudeNoob 2019-05-23 00:17
Hmm, nie wiem o co może chodzić, przepraszam. Od siebie mogę tylko dodać, że powinienieś się zastanowić, gdzie (w kodzie) oczekujesz, że coś się wrzuci, i sprawdzić czy to się tam dzieje, jeśli nie, cofnąć się trochę itd. - enedil 2019-05-23 00:20
Okej, dzięki za pomoc. Logikę programu ogarniam(chociaż też pewnie mogłaby być lepsza), tyle tylko że tracę godziny na szukaniu błędu/rozwiązania w języku którego właściwie nie znam, dlatego właśnie szukam pomocy na forum... może ktoś jeszcze się znajdzie z jakimś pomysłem, zawsze to 'świeże spojrzenie'. - RudeNoob 2019-05-23 00:26

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: CCBot