import re
from functools import partial
import tornado.ioloop
import tornado.iostream
import tornado.httpserver
import tornado.netutil
import tornado.tcpserver
import tornado.web
messages = []
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.set_header('Content-Type', 'text')
self.write('\n'.join(messages))
def accept(connection, address):
stream = tornado.iostream.IOStream(connection)
callback = partial(talk, stream)
stream.read_until('\n', callback)
quit_pattern = re.compile('quit\s*', re.IGNORECASE)
def talk(stream, message):
stream.write('I got your message: %r\r\n' % message)
if quit_pattern.match(message):
stream.close()
else:
messages.append(message)
# Read next message.
callback = partial(talk, stream)
stream.read_until('\n', callback)
if __name__ == "__main__":
application = tornado.web.Application(handlers=[
(r"/", MainHandler),
])
application.listen(8888)
unix_socket = tornado.netutil.bind_unix_socket('/tmp/sock.sock')
tornado.netutil.add_accept_handler(unix_socket, accept)
tornado.ioloop.IOLoop.instance().start()
You can run "telnet -u /tmp/sock.sock" on the terminal and talk to the application:
Trying /tmp/sock.sock...
Connected to (null).
Escape character is '^]'.
asdf
I got your message: 'asdf\r\n'
foo
I got your message: 'foo\r\n'
quit
I got your message: 'quit\r\n'
Connection closed by foreign host.
To demonstrate data-sharing between the unix socket listener and the HTTP server, the unix socket server adds each message to the global 'messages' list. The HTTP server presents a page on
http://localhost:8888 with all the messages received.
(This is not relevant to Srini's question
right now, but it harkens back to our discussion about making IOStream coroutine-friendly. Once those changes are complete, accept() and talk() can be neatly combined into one coroutine.)