如何在使用异步websockets时保持会话活动?

时间:2017-02-06 17:56:45

标签: python session asynchronous websocket python-asyncio

我有这个代码使用serialize()async python库与websocket api进行交互:

websokets

所以我在main.py中有以下内容:

#!/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()

问题是它没有保留授权会话,所以这是输出:

from webclass import *

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

如您所见,登录调用正常,但在root@ubupc1:/home/dinocob# python3 test.py asd@gmail.com {'error': {'message': 'Please log in.', 'code': 'AuthorizationRequired'}} 函数中调用和发送hello时,会话不一样。

  • 在哪里销毁会话?
  • 我怎么能保留它(没有大幅度的保存) 修改我的班级结构)?

2 个答案:

答案 0 :(得分:2)

我认为问题可能出在context_manager或with statement.

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

当您使用'上下文应该如下所示(更好的异常处理和上下文管理器的所有好处,因此您可以将__async_send_recieve的流程描绘为:

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

为了证明这一理论,在__aenter____aexit__函数中添加一个print语句,您应该能够更好地可视化上下文管理器流程。

修复方法是在每个请求中重新授权。但我想你想要做的是让你的测试类来管理用于与远程服务器通信的上下文。 (我的异步语法在这里可能有点不对,但在概念上与上下文管理器有关):

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'})

答案 1 :(得分:0)

从您的代码中看,服务器似乎记住了每个websocket连接的登录状态,因此您无需在客户端执行任何操作。

  

在哪里销毁会议?

会话在服务器端被销毁。

  

我怎么能保留它?

修复服务器错误?