2017-02-06 22 views
5

Mam ten kod do interakcji z API websocket wykorzystaniem async i websokets bibliotek Pythona:Jak utrzymać aktywność sesji podczas używania async websockets?

#!/usr/bin/env python3 

import sys, json 
import asyncio 
from websockets import connect 

class AsyncWebsocket(): 
    async def __aenter__(self): 
     self._conn = connect('wss://ws.myws.com/v2') 
     self.websocket = await self._conn.__aenter__()   
     return self 

    async def __aexit__(self, *args, **kwargs): 
     await self._conn.__aexit__(*args, **kwargs) 

    async def send(self, message): 
     await self.websocket.send(message) 

    async def receive(self): 
     return await self.websocket.recv() 

class mtest(): 
    def __init__(self, api_token): 
     self.aws  = AsyncWebsocket() 
     self.loop  = asyncio.get_event_loop() 
     self.api_token = api_token 

     self.authorize() 

    def authorize(self): 
     jdata = self.__async_exec({ 
            'authorize': self.api_token 
            }) 

     try: 
      print (jdata['email']) 
      ret = True 
     except: 
      ret = False 

     return ret 

    def sendtest(self): 

     jdata = self.__async_exec({ 
            "hello": 1 
            }) 

     print (jdata) 


    def __async_exec(self, jdata): 
     try: 
      ret = json.loads(self.loop.run_until_complete(self.__async_send_recieve(jdata))) 
     except: 
      ret = None 

     return ret 

    async def __async_send_recieve(self, jdata): 
     async with self.aws: 
      await self.aws.send(json.dumps(jdata)) 
      return await self.aws.receive() 

Więc mam następujący w main.py:

from webclass import * 

a = mtest('12341234') 
print (a.sendtest()) 

Problemem jest to, że nie robi” t zachowaj autoryzowaną sesję, więc jest to wyjście:

[email protected]:/home/dinocob# python3 test.py 
[email protected] 
{'error': {'message': 'Please log in.', 'code': 'AuthorizationRequired'}} 

Jak widzisz, logowanie jest worki ng ok, ale podczas wywoływania i wysyłania funkcji hello w sendtest sesja nie jest taka sama.

  • Gdzie jest zniszczona sesja?
  • Jak mogę go zachować (bez drastycznego modyfikowania struktury klasowej przez )?
+0

Gdzie zapisujesz swój autoryzowany token po zalogowaniu? – MooingRawr

+0

Do 'self.api_token' wewnątrz funkcji' __init__'. Ale działa dobrze; problem pojawia się podczas wywoływania funkcji '__async_send_recieve' Myślę, że ... – harrison4

Odpowiedz

1

Myślę, że problem może być w context_manager lub withstatement.

async def __async_send_recieve(self, jdata): 
    async with self.aws: 
     await self.aws.send(json.dumps(jdata)) 
     return await self.aws.receive() 

Po wywołaniu „z” kontekst powinien odgrywać się następująco (z lepszą obsługę wyjątków i wszystkie korzyści płynące z menedżerów kontekstowych , więc można zobrazować przepływ __async_send_recieve jak:

 self.aws.__aenter__() 
     self.aws.send(data) 
     self.aws.receive() 
     self.aws.__aexit__() 

Aby udowodnić tę teorię, dodać oświadczenie druku do zabawy __aenter__ i __aexit__ i powinieneś być w stanie lepiej zwizualizować przepływ menedżera kontekstu.

Poprawka polegałaby na ponownym autoryzowaniu w każdym żądaniu. Ale wyobrażam sobie, że chcesz, aby twoja klasa testowa zarządzała kontekstem używanym do komunikacji ze zdalnym serwerem. (Moja składnia asynchroniczna może być tu trochę nie tak, ale konceptualnie z menedżerami kontekstów):

class Mtest(): 
    def __init__(self, ...): 
      ... 

    def __enter__(self,): 
     self.authorize() 

    def __exit__(self): 
     self.deauthorize() 

    async def make_async_request(self, data): 
     await self.aws.send(json.dumps(data)) 
     return await self.aws.receive() 

with Mtest(api_key) as m: 
    m.make_async_request({'test_data': 'dummy_test_data'}) 
    m.make_async_request({'more_data': 'more_mock_data'}) 
0

Wygląda na to, że z twojego kodu serwer zapamiętuje status logowania dla każdego połączenia z websocket, więc nie musisz nic robić po stronie klienta.

Gdzie jest zniszczona sesja?

Sesja jest niszczona po stronie serwera.

Jak mogę go zachować?

Napraw błąd serwera?