chat demo
做一个tornado+websocket chat
里面做了长连接的代码,暂时没有实现,下一篇补上
1 import logging 2 import os.path 3 import uuid 4 import tornado.httpserver 5 import tornado.ioloop 6 import tornado.options 7 import tornado.web 8 import tornado.websocket 9 import time 10 11 12 def send_message_ws(message): 13 for handler in ChatSocketHandler.socket_handlers: 14 try: 15 handler.write_message(message) 16 except: 17 logging.error('Error sending message', exc_info=True) 18 19 20 def send_message_lp(message): 21 for handler in ChatSocketHandler.socket_handlers: 22 try: 23 handler.write_message(message) 24 except: 25 logging.error('Error sending message', exc_info=True) 26 27 for callback in ChatPollHandler.callbacks: 28 try: 29 callback(message) 30 except: 31 logging.error('Error in callback', exc_info=True) 32 ChatPollHandler.callbacks = set() 33 34 35 class ChatPollHandler(tornado.web.RequestHandler): 36 callbacks = set() 37 users = set() 38 39 @tornado.web.asynchronous 40 def get(self): 41 ChatPollHandler.callbacks.add(self.on_new_message) 42 self.user = user = self.get_cookie('user') 43 if not user: 44 self.user = user = str(uuid.uuid4()) 45 self.set_cookie('user', user) 46 if user not in ChatPollHandler.users: 47 ChatPollHandler.users.add(user) 48 send_message_lp('A new user has entered the long pollchat room.') 49 50 def on_new_message(self, message): 51 if self.request.connection.stream.closed(): 52 return 53 self.write(message) 54 self.finish() 55 56 def on_connection_close(self): 57 ChatPollHandler.callbacks.remove(self.on_new_message) 58 ChatPollHandler.users.discard(self.user) 59 send_message_lp('A user has left the long poll chat room.') 60 61 def post(self): 62 send_message_lp(self.get_argument('text')) 63 64 65 class MainHandler(tornado.web.RequestHandler): 66 def get(self): 67 self.render('index.html') 68 69 70 class ChatSocketHandler(tornado.websocket.WebSocketHandler): 71 socket_handlers = set() 72 73 def open(self): 74 ChatSocketHandler.socket_handlers.add(self) 75 76 def on_close(self): 77 ChatSocketHandler.socket_handlers.remove(self) 78 send_message_ws('A user has left the socket chat room.') 79 80 def on_message(self, message): 81 send_message_ws(message) 82 83 84 def send_test(): 85 i = 0 86 while True: 87 send_message_ws(str(i)) 88 i = i + 1 89 time.sleep(1) 90 91 92 def main(): 93 #thread.start_new_thread(send_test, ()) 94 settings = { 95 'template_path': os.path.join(os.path.dirname(__file__), 'templates'), 96 'static_path': os.path.join(os.path.dirname(__file__), 'static') 97 } 98 application = tornado.web.Application( 99 [('/', MainHandler), ('/poll', ChatPollHandler), ('/socket', ChatSocketHandler)], **settings) 100 http_server = tornado.httpserver.HTTPServer(application) 101 http_server.listen(8080) 102 tornado.ioloop.IOLoop.instance().start() 103 104 if __name__ == '__main__': 105 main()
html部分
<!DOCTYPE html> <html> <head> <title>chat demo</title> </head> <script src=""></script> <script src=""></script> <script> function test(ts) { $("#name_form").hide() $("#msg_form").show() websocket($("#name").val()) return false } </script> <body> <p id="name_form">name:<input id="name"></input> <input type="button" onclick="test()" value="进入"></p> <form style="display:none" id="msg_form" action="/socket" method="post"> <textarea id="text"></textarea> <input type="submit" value="发言"/> </form> <div id="msg"></div> </body> </html>
js部分
function websocket(name) {
var $msg = $('#msg');
var $text = $('#text');
var WebSocket = window.WebSocket || window.MozWebSocket;
var socket = new WebSocket('ws://192.168.10.148:8080/socket');
// 打开Socket
socket.onopen = function(event) {
// 发送一个初始化消息
socket.send('I am ' + name + ' I come here!');
// 监听消息
socket.onmessage = function(event) {
$msg.append('
' + event.data + '
');
};
$('#msg_form').submit(function() {
socket.send(name + " say: " + $text.val());
$text.val('').select();
return false;
});
// 监听Socket的关闭
socket.onclose = function(event) {
$msg.append('server is close');
socket.close()
};
};
}