2017-08-07 15 views
0

私は、単純なWebソケットサーバーをPythonでthis moduleを使用して実装しようとしています。学習目的のために、サーバーは受け取ったものの逆のバージョンで返信する必要があります。たとえば、クライアントが「Hello Server」を送信する場合、サーバーは「revre olleH」と応答する必要があります。 consumer()producer()機能/コルーチンの例は、ドキュメントで提供されなかったので、私のコードがドキュメントにhereSimpe Python Webソケットサーバーの作成

をオフに基づいており、私はそれらを作成で刺しを取ったが、私は私には明白ではない何かを誤解していと思います。コードは現在、クライアントが送信したものの逆のバージョンではなく、文字列'nothing'を返しています。

FYIでは、使用しているマシンにPython 3.4.3が含まれているため、そのバージョンに対応するためにコードを調整する必要がありました。だからこそ、もっと新しいコードがコメントアウトされているのが分かります。私はこのことを学ぶので、たくさんのドキュメントも含まれています。今

、codez ...

index.py:index.htmlを

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 



######################### 
# Dependencies 
######################### 
# asyncio 
# websockets 



######################### 
# Modules 
######################### 

import asyncio 
import websockets 



######################### 
# Functions 
######################### 

# async indicates an asynchronous function. 
# Calling them doesn't actually run them, 
# but instead a coroutine object is returned, 
# which can then be passed to the event loop to be executed later on. 

# Python ≥ 3.5: async def producer(reply): 
@asyncio.coroutine 
def producer(reply=None): 
    """Sends the reply to producer_handler.""" 

    if reply is None: 
     return 'nothing' 
    else: 
     return reply 

# Python ≥ 3.5: async def consumer(message): 
@asyncio.coroutine 
def consumer(message): 
    """Reverses message then sends it to the producer.""" 

    reply = message[::-1] 
    #await producer(reply) 
    yield from producer(reply) 

# async def consumer_handler(websocket): 
@asyncio.coroutine 
def consumer_handler(websocket): 
    """Handles incoming websocket messages.""" 

    while True: 
     # await calls an asynchronous function. 
     #message = await websocket.recv() 
     message = yield from websocket.recv() 
     # Python ≥ 3.5: await consumer(message) 
     yield from consumer(message) 

#async def producer_handler(websocket): 
@asyncio.coroutine 
def producer_handler(websocket): 
    """Handles outgoing websocket messages.""" 

    while True: 
     #message = await producer() 
     message = yield from producer() 
     #await websocket.send(message) 
     yield from websocket.send(message) 

#async def handler(websocket, path): 
@asyncio.coroutine 
def handler(websocket, path): 
    """Enables reading and writing messages on the same websocket connection.""" 

    # A Future is an object that is supposed to have a result in the future. 

    # ensure_future: 
    # schedules the execution of a coroutine object, 
    # wraps it in a future, then returns a Task object. 
    # If the argument is a Future, it is returned directly. 

    # Python ≥ 3.5 
    #consumer_task = asyncio.ensure_future(consumer_handler(websocket)) 
    #producer_task = asyncio.ensure_future(producer_handler(websocket)) 

    consumer_task = asyncio.async(consumer_handler(websocket)) 
    producer_task = asyncio.async(producer_handler(websocket)) 

    # .wait: 
    # wait for the Futures and coroutine objects given 
    # by the sequence futures to complete. Coroutines will be 
    # wrapped in Tasks. Returns two sets of Future: (done, pending). 

    #done, pending = await asyncio.wait(
    done, pending = yield from asyncio.wait(
     # The futures. 
     [consumer_task, producer_task], 
     # FIRST_COMPLETED: the function will return when 
     # any future finishes or is cancelled. 
     return_when=asyncio.FIRST_COMPLETED, 
    ) 
    for task in pending: 
     task.cancel() 



######################### 
# Start script 
######################### 

def main(): 

    # Creates a WebSocket server. 
    start_server = websockets.serve(handler, '127.0.0.1', 8000) 

    # Get the event loop for the current context. 
    # Run until the Future is done. 
    asyncio.get_event_loop().run_until_complete(start_server) 

    # Run until stop() is called. 
    asyncio.get_event_loop().run_forever() 



######################### 
# Script entry point. 
######################### 

if __name__ == '__main__': 
    main() 

<!DOCTYPE html> 
<html> 
    <head> 
     <title>WebSocket demo</title> 
    </head> 
    <body> 
     <script> 
      // Create the websocket. 
      var ws = new WebSocket("ws://127.0.0.1:8000/"), 
       messages = document.createElement('ul'); 

      // Called when the websocket is opened. 
      ws.onopen = function(event) { 
       ws.send('Hello Server!'); 
      }; 

      // Called when a message is received from server. 
      ws.onmessage = function(event) { 
       var messages = document.getElementsByTagName('ul')[0], 
        message = document.createElement('li'), 
        content = document.createTextNode(event.data); 
       message.appendChild(content); 
       messages.appendChild(message); 
      }; 
      document.body.appendChild(messages); 
     </script> 
    </body> 
</html> 

答えて

1

ないこの上完全に確認してください、私は考えますあなたはドキュメントを誤解しました。消費者は生産者を呼び出すべきではありません。

"Hello Server!" HTMLファイルの送信はconsumer_handlerからconsumerからproducerになりますが、yield fromという文は、逆の文字列がconsumer_handlerになり、結果はyield from consumer(message)となります。一方

producer_handlerは、HTMLファイルに送信されますnothingを作成するものである、(message = yield from producer()から)引数なしproducer何度も呼び出します。 consumerの文字列は受信されません。

代わりに、コンシューマがプッシュしてプロデューサを取得するキューなどがあります(like in this example)。

ありがとうございました。

関連する問題