2017-08-07 85 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获得的东西。

谢谢。

相关问题