Created
March 19, 2014 06:10
-
-
Save gf0842wf/9636336 to your computer and use it in GitHub Desktop.
tornado同时提供http和tcp服务
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding:utf-8 -*- | |
import tornado.ioloop | |
import tornado.web | |
from tornado.ioloop import IOLoop | |
from functools import partial | |
import socket, Queue | |
fd_map = {} # 可以使用weakref.WeakValueDictionary | |
message_queue_map = {} # 可以使用weakref.WeakValueDictionary | |
ioloop = IOLoop.instance() | |
def init_socket(server_address): | |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
sock.setblocking(0) | |
sock.bind(server_address) | |
sock.listen(200) | |
fd = sock.fileno() | |
fd_map[fd] = sock | |
return fd | |
def handle_client(fd, event, cli_addr): | |
s = fd_map[fd] | |
if event & IOLoop.READ: | |
data = s.recv(1024) | |
if data: | |
print "Recv:", data, cli_addr | |
ioloop.update_handler(fd, IOLoop.WRITE) | |
message_queue_map[s].put(data) | |
else: | |
print "Closing:", cli_addr | |
ioloop.remove_handler(fd) | |
s.close() | |
del message_queue_map[s] | |
if event & IOLoop.WRITE: | |
try: | |
next_msg = message_queue_map[s].get_nowait() | |
except Queue.Empty: | |
print "Queue empty:", cli_addr | |
ioloop.update_handler(fd, IOLoop.READ) | |
else: | |
print "Send:", next_msg, cli_addr | |
s.send(next_msg) | |
if event & IOLoop.ERROR: | |
print "Exception on:", cli_addr | |
ioloop.remove_handler(fd) | |
s.close() | |
del message_queue_map[s] | |
def handle_server(fd, event): | |
s = fd_map[fd] | |
if event & IOLoop.READ: | |
conn, cli_addr = s.accept() | |
conn.setblocking(0) | |
conn_fd = conn.fileno() | |
fd_map[conn_fd] = conn | |
handle = partial(handle_client, cli_addr=cli_addr) | |
ioloop.add_handler(conn_fd, handle, IOLoop.READ) | |
message_queue_map[conn] = Queue.Queue() # 创建对应的消息队列 | |
class MainHandler(tornado.web.RequestHandler): | |
def get(self): | |
print "http test" | |
self.write("Hello") | |
application = tornado.web.Application([ | |
(r"/", MainHandler), | |
]) | |
if __name__ == "__main__": | |
application.listen(8880) | |
fd = init_socket(("0.0.0.0", 8881)) | |
ioloop.add_handler(fd, handle_server, IOLoop.READ) | |
ioloop.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
mark: 最好不用使用weakref, 测试时,因为sock释放会导致add_handler报错.