开发者

Using RPC over email?

Can someone tell me how they have done this in some form, be it XML-RPC, SOAP, bespoke etc. Not too worried on the packet format.

I am interested in 开发者_Go百科doing some sort of RPC over email, setting up a program to receive commands via email from another application(s) or even from users on a subscription list. Basically the idea is you give someone the email address and then send messages to active commands, and the response is back in email. A good example of where I would be taking this is maybe a chess program, where time is irrelevant but delivery is everything and sequential ordering of moves is a given.

I would be most interested in the experiences of others, especially with the nature of email and any idiosyncratic behaviour that I should be aware of.

I have quite a bit of experience of RPC over Message Queues and asynchronous delivery, but would like to come up with a solution where I shift the communications on to hotmail or gmail, freeing up my servers and the headache of the asynchronous intercoms.


I'm already doing this with Google AppEngine and Python. It's really simple.

In your app.yaml file you need to setup that you will using the email service and you file to manage them:

application: appname
version: 1
runtime: python
api_version: 1

handlers:
- url: /_ah/mail/.+
  script: mail.py
  login: admin

inbound_services:
- mail

Then create a mail.py file with something like this:

#!/usr/bin/env python

import rfc822
import logging

from google.appengine.ext import db
from google.appengine.ext import webapp 
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler 
from google.appengine.ext.webapp.util import run_wsgi_app

class LogSenderHandler(InboundMailHandler):
    def receive(self, message):
        service_name, service_email = rfc822.parseaddr(message.to)
        service_request = service_email.split('@').pop(0)
        sender_name, sender_email = rfc822.parseaddr(message.sender)

        logging.info('Service `%s` activated by `%s`.' % (service_request, sender_email))

if __name__ == '__main__':
    application = webapp.WSGIApplication(
        [LogSenderHandler.mapping()])
    run_wsgi_app(application)

All you need to do is send an email to servicename@appname.appspotmail.com. Voila!


You could use fetchmail like this:

#!/bin/bash
while sleep 1
do
    fetchmail --idle --mda python program_that_accepts_email_with_headers_on_stdin.py
done

Then Your program can do various things from querying database, through using some http services, to sending an email to someone. The way it works is first it sleeps for a second, then it checks the email box according to settings You need to place in ~/.fetchmailrc (read man fetchmail for info on how to do that). If it finds any email, it invokes Your program, if not and the loop goes back to the start point. If it doesn't find any emails, it waits until an email will arrive (or the mail server will restart).

The bottom line is that if the said system is not heavily loaded, it will almost instantly react to emails (usually You send an email with command, wait 3 seconds and You have a reply in Your inbox).

NOTE: halting (--idle) only works with IMAP servers. With pop servers You could do the same but sleep 10 seconds instead of 1. Sleeping for 1 second is good because Your program may be ultra-fast and may create an infinite loop with other program (f.e. mailer daemon saying someone is on vacation) and usually it would be good to at least limit their looping frenzy to 1 email/second. I learned it the hard way :) Sleeping will be bad if You would like to process more than 1 email/second. If so, switch sleep 1 to true.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜