早期網頁更新訊息必須 Refresh 整個頁面,這使得網頁互動效果有一定的限制在。後來 AJAX 的火紅,使得網頁的 UX 提升到了另一個境界。
但 AJAX 仍無法有效率的處理 Realtime 的訊息傳遞,最多只能做到 Realtime-like,畢竟仍是 client 主動,server 被動,若 server 有資料更新,client 也只能透過 polling 的方式來偵測資料是否有更新,而這不但 client 辛苦,server 更是得面臨大量的 garbage packet。
只要瀏覽器支援,其實透過 WebSocket 來處理是更理想的。WebScoket 跟傳統 socket 在使用上非常相似,都是由 client 主動連線,並在正常情況下可保持連線,使得 server 可直接將訊息送到「連接中」的 client。
程式碼如下
Server side
chatroom.py
import tornado.ioloop
import tornado.web
from tornado import websocket
clients = []
class ChatRoom(websocket.WebSocketHandler):
def open(self):
clients.append(self)
def on_close(self):
clients.remove(self)
def on_message(self, message):
for client in clients:
client.write_message(message)
application = tornado.web.Application([
(r"/", ChatRoom),
])
if __name__ == "__main__":
application.listen(8000)
tornado.ioloop.IOLoop.instance().start()
Client side
chatroom.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Chat Room</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
var socket = new WebSocket("ws://localhost:8000/");
socket.onmessage = function(event) {
$("#message").append("<div>" + event.data + "</div>");
}
$("#send").click(function() {
socket.send($("#text").val());
$("#text").val("").select();
});
});
</script>
</head>
<body>
<div id="message"></div>
<textarea id="text"></textarea>
<input type="button" id="send" value="send" />
</body>
</html>
安裝 Tornado 不多提,實際執行結果如下:
執行 chatroom.py
多開 chatroom.html,就可以進行聊天了