2017-08-07 59 views
0

我想通過使用this module在Python中實現一個簡單的網絡套接字服務器。爲了學習的目的,服務器應該以它收到的反向版本回復。例如,如果客戶端發送「Hello Server」,則服務器應以「revreS olleH」響應。我的代碼是基於關閉文檔here創建一個Simpe Python網絡套接字服務器

由於consumer()producer()功能/協同程序的例子並沒有在文檔中提供的,我參加了一個刺創造他們,但想到我誤解並不明顯,我的東西。該代碼當前返回字符串'nothing'而不是客戶端發送的反向版本。

僅供參考,由於我使用的機器是Python 3.4.3,因此必須調整代碼以適應該版本。這就是爲什麼現在你會看到更新的代碼被註釋掉的原因。當我學習這些東西時,也包含了很多文檔。

現在,codez ...

index.py

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

的index.html

<!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_handlerconsumerproducer,但yield from語句意味着反向字符串結束於consumer_handler,作爲yield from consumer(message)的結果。

在另一方面,producer_handler調用producer很多次都沒有一個參數(從message = yield from producer()),這是創建一個被髮送到HTML文件nothing。它不會收到consumer的字符串。

相反,應該有一個隊列或消費者推到並且生產者從like in this example獲得的東西。

謝謝。