最近写个网页版的游戏,遇到了一个问题就是如果有一个人出牌,怎么让其他玩家立刻看到这个玩家所出的牌。
搜索半天无果,不过倒是发现了这类问题都可以归结为一个问题就是B/S架构程序的协同处理问题。
也发了个贴http://topic.youkuaiyun.com/u/20091028/20/e3be739d-6551-4d3f-acb7-305ac995ded1.html,寻求好的解决办法。
最后决定用Ajax的comet方式。但是鉴于对服务器有要求,感觉浏览器也不一定全部支持,所以最后决定自己实现。
实现的类视图如下

举例,比如用户进入房间,首先通过EnterBoardAction进入房间,并列出所有在房间内的人。之后通过JavaScript向服务器提出UpdateInfoAction请求,并向Subject注册,该请求通过wait方法,将请求挂起。
当有用户在进入房间时,调用Subject的notifyAllObserver方法,然后所有在房间内的其他用户可以即时更新新进来的用户的信息。
下面展示代码(由于篇幅有限,紧展示部分代码):
查看Board的jsp的JavaScript:
查看Board的jsp中的JavaScript
1
<script type="text/javascript" src="js/AjaxRequest.js">
2
</script>
3
<script type="text/javascript" language="javascript">
4
function updateInfo()
{
5
var loader = new net.AjaxRequest("updateInfo.action", update, onerror, "POST");
6
}
7
8
window.onload = updateInfo();
9
10
function update()
{
11
var username = document.createTextNode(this.req.responseText);
12
document.getElementById("userList").appendChild(username);
13
updateInfo();
14
}
15
16
function onerror()
{
17
userList.innerHTML = this.req.responseText;
18
}
19
20
function enterBoard(board_id, room_id)
{
21
new net.AjaxRequest1("enterBoards.action?board_id=" + board_id + "&room_id=" + room_id, enterboardComplete, onerror, "POST");
22
}
23
24
function enterboardComplete()
{
25
var loader2 = null;
26
}
27
</script>
AjaxRequest.js:
AjaxRequest的部分代码
1
var net = new Object();
2
net.AjaxRequest = function(url, onload, onerror, method, params)
{
3
this.req = null;
4
this.onload = onload;
5
this.onerror = (onerror) ? onerror : this.defaultError;
6
this.loadDate(url, method, params);
7
};
8
9
net.AjaxRequest.prototype.loadDate = function(url, method, params)
{
10
if (!method)
{
11
method = "GET";
12
}
13
if (window.XMLHttpRequest)
{
14
this.req = new XMLHttpRequest();
15
} else if (window.ActiveXObject)
{
16
this.req = new ActiveXObject("Microsoft.XMLHTTP");
17
}
18
if (this.req)
{
19
try
{
20
var loader = this;
21
this.req.onreadystatechange = function()
{
22
net.AjaxRequest.onReadyState.call(loader);
23
};
24
this.req.open(method, url, true);
25
//this.req.send(params);
26
this.req.send(null);
27
} catch (err)
{
28
this.onerror.call(this);
29
}
30
}
31
};
32
33
net.AjaxRequest.onReadyState = function()
{
34
var req = this.req;
35
var ready = req.readyState;
36
if (ready == 4)
{
37
if (req.status == 200)
{
38
this.onload.call(this);
39
} else
{
40
this.onerror.call(this);
41
}
42
}
43
};
44
45
net.AjaxRequest.prototype.defaultError = function()
{
46
alert("error fetching data!"
47
+ "\n\nreadyState:" + this.req.readyState
48
+ "\nstatus: " + this.req.status
49
+ "\nheaders: " + this.req.getAllResponseHeaders());
50
};
服务器端代码简单,在上方类视图中有显示,固不在此列出。
这里也只是提供一个思路,服务器端实现其实可以使多样的,对任何语言理论上都起作用。另外,这种实现方式是我想出的对服务器不论是带宽还是资源压力最小的,调用wait函数,而没有用死循环也是出于这个原因。
在此也希望如果大家有什么更好的方式解决类似问题,请回复一起讨论