Python async websockets keep session alive

edited February 10

I'm trying to connect to binary websocket using python, I make this code to interact with api:

`#!/usr/bin/env python3

import json
import asyncio
from websockets import connect

class AsyncWebsocket():

async def __aenter__(self):
    self._conn = connect("wss://ws.binaryws.com/websockets/v3")
    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 test_class():

def __init__(self, api_token):
    self.aws        = AsyncWebsocket()
    self.api_token  = api_token

def autorize(self):
    req = self.__async_exec({
                                "authorize": self.api_token
                            })
    return req

def send_test(self):

    con = self.autorize()

    if con["error"]["code"] == "InvalidToken":
        return "LOGIN FAIL"
    else:
        print("Connected!")

    req = self.__async_exec({
                                "balance": 1
                            })
    return req

def __async_exec(self, req):

    try:
        loop = asyncio.get_event_loop()
        ret  = json.loads(loop.run_until_complete(self.__async_send_recieve(req)))
    except:
        ret  = None

    return ret

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

a = test_class("token")
print (a.send_test())`

I'm getting the following output:

Connected!
{"echo_req": {"balance": 1}, "error": {"code": "AuthorizationRequired", "message": "Please log in."}, "msg_type": "balance" }

As you can see, the authorize call is working ok, but when I try to make a second call -balance- seems like the session is not the same or it is destroyed. How can I keep my session alive or prevent it from being destroyed?

Comments

  • Please note that you need to make balance call only when you receive authorize response.

    con = self.autorize()
    
        if con["error"]["code"] == "InvalidToken":
            return "LOGIN FAIL"
        else:
            print("Connected!")
    
        req = self.__async_exec({
                                    "balance": 1
                                })
    

    here you are calling balance just after authorize.

  • edited February 10

    My understanding is that, await suspends execution to obtain a result of coroutine execution:

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

    After I make send authorize request, my function should wait for a response and return it:

    return await self.aws.receive()

    At this point, I'm checking if the response returned an error:

    con = self.autorize()
    
    if con["error"]["code"] == "InvalidToken":
        return "LOGIN FAIL"
    

    If so, connection failed message is returned.
    If no errors found, that means authorize went ok and I can make balance request.

    Am I wrong?

Sign In or Register to comment.