Multiplexing an echo server using Diesel concurrent library

Sometimes you need to write a large custom networking application that wants to avoid repeated server initialization code that creates a socket, binds to an address, listens, and handles basic errors. There are numerous Python networking libraries out there to help you to remove boiler-plate code. Here, we can examine such a library called Diesel.

Getting ready

Diesel uses a non-blocking technique with co-routines to write networking severs efficiently. As stated on the website, Diesel's core is a tight event loop that uses epoll to deliver nearly flat performance out to 10,000 connections and beyond. Here, we introduce Diesel with a simple echo server. You also need diesel library 3.0 or any later version. You can do that with pip command: $ pip install diesel >= 3.0.

How to do it...

In the Python Diesel framework, applications are initialized with an instance of the Application() class and an event handler is registered with this instance. Let's see how simple it is to write an echo server.

Listing 2.5 shows the code on the echo server example using Diesel as follows:

#!/usr/bin/env python
# Python Network Programming Cookbook -- Chapter - 2
# This program is optimized for Python 2.7.
# It may run on any other version with/without modifications.
# You also need diesel library 3.0 or any later version

import diesel
import argparse

class EchoServer(object):
    """ An echo server using diesel"""

    def handler(self, remote_addr):
        """Runs the echo server"""
        host, port = remote_addr[0], remote_addr[1]
        print "Echo client connected from: %s:%d" %(host, port)
        
        while True:
            try:
                message = diesel.until_eol()
                your_message = ': '.join(['You said', message])
                diesel.send(your_message)
            except Exception, e:
                print "Exception:",e

def main(server_port):
    app = diesel.Application()
    server = EchoServer()    
    app.add_service(diesel.Service(server.handler, server_port))
    app.run()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Echo server example with Diesel')
    parser.add_argument('--port', action="store", dest="port", type=int, required=True)
    given_args = parser.parse_args()
    port = given_args.port
    main(port)

If you run this script, the server will show the following output:

$ python 2_5_echo_server_with_diesel.py --port=8800
[2013/04/08 11:48:32] {diesel} WARNING:Starting diesel <hand-rolled select.epoll>
Echo client connected from: 127.0.0.1:56603

On another console window, another Telnet client can be launched and the echoing message to our server can be tested as follows:

$ telnet localhost 8800
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello Diesel server ?
You said: Hello Diesel server ?

The following screenshot illustrates the interaction of the Diesel chat server:

How to do it...

How it works...

Our script has taken a command-line argument for --port and passed this to the main() function where our Diesel application has been initialized and run.

Diesel has a notion of service where an application can be built with many services. EchoServer has a handler() method. This enables the server to deal with individual client connections. The Service() method takes the handler method and a port number to run that service.

Inside the handler() method, we determine the behavior of the server. In this case, the server is simply returning the message text.

If we compare this code with Chapter 1, Sockets, IPv4, and Simple Client/Server Programming, in the Writing a simple echo client/server application recipe (listing 1.13a), it is very clear that we do not need to write any boiler-plate code and hence it's very easy to concentrate on high-level application logic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.137.67