2016-05-22 6 views
11

asynciowebsocketsでwebsocketに接続したいと考えています。形式は以下のとおりです。どのように私はこれを達成することができますか?クラスにasyncio websocketを実装するにはどうしたらいいですか?

from websockets import connect 


class EchoWebsocket: 

    def __init__(self): 
     self.websocket = self._connect() 

    def _connect(self): 
     return connect("wss://echo.websocket.org") 

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

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

echo = EchoWebsocket() 
echo.send("Hello!") 
print(echo.receive()) # "Hello!" 

答えて

12

非同期プログラムの書き込み方法は?

  1. あなたはあなたが他のすべてが通常のPythonとほぼ同じであるあなたの非同期プログラム

を開始するevent loopが必要await

  • で のfuncs非同期(async)を呼び出す必要がありasync
  • と非同期のfuncsを定義する必要がありますプログラム。

    import asyncio 
    from websockets import connect 
    
    
    class EchoWebsocket: 
        async def __aenter__(self): 
         self._conn = connect("wss://echo.websocket.org") 
         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() 
    
    
    async def main(): 
        async with EchoWebsocket() as echo: 
         await echo.send("Hello!") 
         print(await echo.receive()) # "Hello!" 
    
    
    if __name__ == '__main__': 
        loop = asyncio.get_event_loop() 
        loop.run_until_complete(main()) 
    

    出力:

    Hello! 
    

    ご覧のとおり、コードはあなたが書いたとほぼ同じです。

    websockets.connectは非同期コンテキストマネージャ(これは__aenter__,__aexit__を使用)に設計されています。接続を解除する必要があります(クラスの初期化中に__init__の非同期バージョンがないため、非同期操作を行うのにも役立ちます)。

    同じようにクラスを整理することをお勧めします。 websocketsを使用しての

    import sys 
    import asyncio 
    from websockets import connect 
    
    
    class EchoWebsocket: 
        def __await__(self): 
         # see: http://stackoverflow.com/a/33420721/1113207 
         return self._async_init().__await__() 
    
        async def _async_init(self): 
         self._conn = connect("wss://echo.websocket.org") 
         self.websocket = await self._conn.__aenter__() 
         return self 
    
        async def close(self): 
         await self._conn.__aexit__(*sys.exc_info()) 
    
        async def send(self, message): 
         await self.websocket.send(message) 
    
        async def receive(self): 
         return await self.websocket.recv() 
    
    
    async def main(): 
        echo = await EchoWebsocket() 
        try: 
         await echo.send("Hello!") 
         print(await echo.receive()) # "Hello!" 
        finally: 
         await echo.close() 
    
    
    if __name__ == '__main__': 
        loop = asyncio.get_event_loop() 
        loop.run_until_complete(main()) 
    

    多くの例あなたが見つけることができます:あなたが実際にいくつかの理由でコンテキストマネージャを使用しない場合しかし、あなたは非同期の初期化と接続解放するためにいくつかの他の非同期機能を作るために新しい__await__メソッドを使用することができますそれはdocsです。

  • +1

    この回答はありがたいです。 – pylang

    +0

    これは返信を受け取った後に閉じます。メッセージを引き続き受信する方法は? – FeedTheWeb

    +0

    @FeedTheWebは、コンテキストマネージャー内で応答を受信し続けるだけです。 –

    関連する問題