2017-03-19 6 views
1

なぜん:コルーチンから呼び出されるコルーチンのウェブソケットを送信できないのはなぜですか?

async def setup(): 
    async with websockets.connect('ws:/ip.address:port') as ws: 
     await ws.send('TEST MESSAGE') 

def startup(): 
    loop = asyncio.new_event_loop() # because it's running in a thread 
    asyncio.set_event_loop(loop) 
    asyncio.ensure_future(setup()) 
    loop.run_forever() 

はWebSocketを下にメッセージを送信し、:

async def setup(): 
    async with websockets.connect('ws:/ip.address:port') as ws: 
     loop = asyncio.get_event_loop() 
     loop.create_task(send_messages(ws)) 

async def send_messages(ws): 
    await ws.send('TEST MESSAGE') 

def startup(): 
    loop = asyncio.new_event_loop() # because it's running in a thread 
    asyncio.set_event_loop(loop) 
    asyncio.ensure_future(setup()) 
    loop.run_forever() 

はないではありませんか?

私はコードを単純化するためにコードをカットしました。必要に応じてオリジナルを投稿することができます。 2番目のバージョンは、ws.send('test')の部分がロギング、デバッグなどをオンにするのを待っているようです。

websocket接続を引数として渡すことに問題があるかどうかは疑問でした。合格したものと受け取ったものをログに記録すると、両方とも同じアドレスの両方で<websockets.client.WebSocketClientProtocol object at 0x04B51A90>が返されます。

私は最終的にやりたい、との質問に答えることができない場合でも、これを行う方法についての提案は歓迎されていることである。 は*からのメッセージを取る:

はかなり永遠にいることを、実行されている2つのコルーチンを持っていますtkinterのGUIから通常の機能によってそこに置かれたキューをwebsocketに送ります。 * websocketからメッセージを受け取り、GUI内のものを変更します。

asyncioというWebSocketライブラリはこれを行う方法ですが、どんな提案にも開放的です。

EDIT:エラーメッセージを追加するのを忘れてしまった!

2017-03-19 10:49:31,103 ERROR asyncio Task exception was never retrieved 
future: <Task finished coro=<send_messages() done, defined at chessboard.py:74> exception=ConnectionClosed('WebSocket connection is closed: code = 1000, no reason.',) created at chessboard.py:103> 
source_traceback: Object created at (most recent call last): 
    File "C:\Program Files (x86)\Python35-32\lib\threading.py", line 882, in _bootstrap 
    self._bootstrap_inner() 
    File "C:\Program Files (x86)\Python35-32\lib\threading.py", line 914, in _bootstrap_inner 
    self.run() 
    File "C:\Program Files (x86)\Python35-32\lib\threading.py", line 862, in run 
    self._target(*self._args, **self._kwargs) 
    File "chessboard.py", line 120, in startup 
    loop.run_forever() 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\base_events.py", line 345, in run_forever 
    self._run_once() 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\base_events.py", line 1312, in _run_once 
    handle._run() 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\events.py", line 125, in _run 
    self._callback(*self._args) 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\tasks.py", line 307, in _wakeup 
    self._step() 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\tasks.py", line 239, in _step 
    result = coro.send(None) 
    File "chessboard.py", line 103, in setup 
    loop.create_task(send_messages(ws)) 
Traceback (most recent call last): 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\tasks.py", line 239, in _step 
    result = coro.send(None) 
    File "C:\Program Files (x86)\Python35-32\lib\asyncio\coroutines.py", line 121, in send 
    return self.gen.send(value) 
    File "chessboard.py", line 81, in send_messages 
    await ws.send(str(message))#seems to be stopping here - why isn't it sending? 
    File "C:\Program Files (x86)\Python35-32\lib\site-packages\websockets\protocol.py", line 309, in send 
    yield from self.ensure_open() 
    File "C:\Program Files (x86)\Python35-32\lib\site-packages\websockets\protocol.py", line 401, in ensure_open 
    raise ConnectionClosed(self.close_code, self.close_reason) 
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1000, no reason. 

答えて

2

websocketを引数として渡しても問題ありません。ここでの問題は、sendコルーチンが待っているとき(エラーメッセージの説明どおり)にwebsocket接続がすでに閉じられていることです。これは、send_messagesタスクがメッセージを送信する前に接続コンテキストが終了したために発生します。

代わりに、この実施例を考えてみます。

async def main(): 
    async with websockets.connect('ws:/ip.address:port') as ws: 
     await send_messages(ws) 

async def send_messages(ws): 
    await ws.send('TEST MESSAGE') 


loop = asyncio.get_event_loop() 
loop.run_until_complete(main) 
+0

質問 - 私が最初の場所でこのようにそれをしなかった理由は、私は永遠に実行している2つの機能が必要であることだった - これは待つ必要はありません'await send_messages(ws)'が終わるまで? –

+1

@JamesWilsonそれは本当にあなたが達成しようとしているものに依存します。しかし、接続コンテキスト(つまり、 'async with'ステートメント)を使用する場合、すべてのwebSocket操作がこのコンテキスト内で行われなければならないことに注意する必要があります。 – Vincent

+0

私は、(asyncio.queueから何かを待っているか、websocketの何かかそれらのことを処理しているので)終了しない2つの関数を取得しようとしています。同じwebsocketにアクセスします。 –

関連する問題