笔者为了体验Pushlet的原理,做了一个聊天室程序,聊天功能对于每个user来说有两个基本功能:
1.发布聊天记录
对于Pushlet来说,是把这个聊天记录clone放到每个subscriber对应的EventQueue中
使用Pushlet提供的publish函数,来完成功能
2.接收别人新的聊天记录
线程轮询EventQueue,取出数据update browser客户端,它可以使用subscribe函数,也可以使用join_listen函数
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Pushlet Chat - Enter</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="chat.css" rel="stylesheet">
<script type="text/javascript"src="../../lib/js-pushlet-client.js"></script>
</head>
<body>
<div id="login" align="center">
<h3>Enter Chat room</h3>
<p>
Nickname: <input type="text" id="nick" name="nick" value="" />
</p>
<p>
<input type="button" id="enter" name="enterButton" value="Join chat room " onClick="joinChatRoom();"/>
</p>
</div>
<div id="content1" align="center" style="display:none">
<div id="content" align="center" style="display:none;border-top-style:Ridge;border-right-style:Ridge;border-left-style:Ridge;
border-bottom-style:Ridge;border-width: 7pt; background-color:#8B008B">
</div>
<div>
<input type="text" id="messageBox"/>
<input type="button" id="messageButton" value="Send" onClick="sendMessage();"/>
</div>
</div>
<script type="text/javascript" src="../../assets/util.js"></script>
<script type="text/javascript" src="../../assets/api.js"></script>
<script type="text/javascript">
function joinChatRoom(){
initDHTML();
var nick = document.getElementById("nick").value;
enterChat(nick);
}
function enterChat(nick){
p_join_listen('/chatroom');
p_publish('/chatroom', 'action', 'enter', 'nick', nick);
document.getElementById("login").style.display="none";
document.getElementById("content1").style.display="block";
document.getElementById("content").style.display="block";
}
// Event Callback: display all events
function onData(event) {
p_debug(false, "pushlet-app", 'event received event=' + event.getEvent() );
var action = event.get('action');
var content = 'none action=' + action;
//alert(action);
if (action == 'send') {
content = '<b>' + event.get('nick') + '</b>: <i>' + event.get('msg') + '</i>';
} else if (action == 'enter') {
content = '<b><i>*** ' + event.get('nick') + ' joined chat ***</i></b>';
} else if (action == 'exit') {
content = '<b><i>*** ' + event.get('nick') + ' left chat ***</i></b>';
}
appendMessage(content);
}
function appendMessage(content){
var div = document.createElement("DIV");
document.getElementById("content").appendChild(div);
div.innerHTML = content;
}
function sendMessage(){
p_publish('/chatroom', 'action', 'send', 'nick', document.getElementById("nick").value, 'msg', document.getElementById("messageBox").value);
}
</script>
<script type="text/javascript">p_embed()</script>
</body>
</html>
注意:需要特别指出的是,每个Join到server的user,会对应一个消费线程,而发布消息的线程只有一个,因此对于普通的web JSP container来说,如果有400个user在聊天室,那么server对应有400个线程在轮询EventQueue,并且会发送心跳包来保证Keep-live没有timeout,开销会非常大,有没有更好的设 计来避免线程的开销呢?希望大家一起思考。
Pushlet的设计思想相对来说比较简单,有空大家可以看它的源代码,分析看看有没有更好的实现方法