最近写个网页版的游戏,遇到了一个问题就是如果有一个人出牌,怎么让其他玩家立刻看到这个玩家所出的牌。最后自己用JavaScript模仿类似Ajax的comet方式实现。
最近写个网页版的游戏,遇到了一个问题就是如果有一个人出牌,怎么让其他玩家立刻看到这个玩家所出的牌。
搜索半天无果,不过倒是发现了这类问题都可以归结为一个问题就是B/S架构程序的协同处理问题。
也发了个贴http://topic.csdn.net/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的部分代码
1var net = new Object();
2net.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
9net.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
33net.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
45net.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函数,而没有用死循环也是出于这个原因。
在此也希望如果大家有什么更好的方式解决类似问题,请回复一起讨论