Use Python's tornado framework to implement a simple WEBQQ robot

Source: Internet
Author: User
I'm going to run WEBQQ alone, starting with a direct copy of Pyxmpp2 's Mainloop, but running up a lot of problems, so I've researched the network programming using Tornado (here), so I gave up Pyxmpp2 's Mainloop, overriding with tornado

First release the project code
Introduction

WEBQQ protocol is a set of HTTP-based QQ protocol, and the request is too slow to use the Python urllib2 Library, because HTTP itself uses the socket request, so instead of using the multiplexed I/O model, and tornado simple and efficient, It's easy to get started after you've seen the code. Platform compatibility is good, so choose Tornado as the network framework.
Principle

First, a Httpstream class is implemented, and its main interface is the Add_request method, which accepts a required parameter: request is a urllib2. An instance of request, and an optional parameter: Readback is a read function that accepts a response parameter returned by a urllib2.urlopen (request) with the following code:

Class Httpstream (object):  # Omit several code  def add_request (self, request, readback = None):    If not isinstance ( Request, Urllib2. Request):      raise ValueError, "not a invaid requset"    # here is easy to trigger timeout exception, omit handling exception code    sock, data = Self.http_ Sock.make_http_sock_data (Request)    FD = Sock.fileno ()    self.fd_map[fd] = sock    SELF.FD_REQUEST_MAP[FD] = Request    callback = partial (self._handle_events, request, data, readback)    Self.ioloop.add_handler (FD, Callback, Ioloop.write)

Httpstream.add_request will urllib2. The request instance resolves a socket and a data for the socket to send. The previous article describes that Tornado.ioloop.IOLoop.add_handler is used to register a socket, which requires three parameters: The file descriptor of the socket, the callback that accepts the file descriptor and event arguments, and the registered event.

The callback we used was httpstream._handle_events:

Class Httpstream (object): # Omit several code def _handle_events (self, request, data, Readback, FD, Event): "" "for handling Tornado events Arguments: ' Request '-urllib.      Request ' data '-socket to write ' readback '-read function The above parameters should use the partial encapsulation and then take this method as Ioloop.add_handler callback ' FD '-ioloop Pass file Descriptor ' event '-Ioloop pass Tornado "" "s = self.fd_map[fd] If event & Ioloop.rea       D: # omit error Handling RESP = Self.http_sock.make_response (s, request) args = Readback (resp) s.setblocking (False) If args and Len (args) = = 3:t = Threading. Thread (target = self.add_delay_request, args = args) T.setdaemon (True) T.start () if args and Len (args) = = 2:self.add_request (*args) Self.ioloop.remove_handler (FD) if event & Ioloop.write:s.sendall (DA    TA) if Readback:self.ioloop.update_handler (FD, Ioloop.read) Else:self.ioloop.remove_handler (FD) If event & IOLoop.ERROR:pass

It accepts the parameters above the comments written very clearly, do not explain, so this method through the Functools.partial encapsulation as callback passed to Tornado.ioloop.IOLoop.add_handler, and register as a write event, To send an HTTP request.

The httpstream._handle_events is used to handle events that send an HTTP request when the event is written (according to Urllib2. Request generated for the data sent), and determine whether there is read function, there is register read event, when the event is read to build a response from the socket and passed to the Read function, the Read function will return 3 values, namely: The next request, the requested read function (can be none, For none, only requests are not read), delay of the next request (add this request after a long event, optional, in seconds)

The next request is determined based on the three values returned by the Read function, and a series of requests are completed. For a more complete code, see the project code given at the beginning of the article

When HTTPStream.http_sock.make_response executes, the socket is set to block because Httplib will appear if no blocking is set. Badstatusline exception. The read function completes, re-set the socket to non-blocking, and remove the socket (although this processing but QQ connection time is slightly longer or will trigger the Httplib.badstatusline exception)

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.