B/S协同处理的简单实现(reversed Ajax的comet方式Java山寨版)

本文探讨了在B/S架构下网页版游戏中实现实时协同处理的方法,通过使用Ajax的Comet技术,使得服务器能够推送实时信息给客户端,解决了游戏中玩家操作同步的问题。

最近写个网页版的游戏,遇到了一个问题就是如果有一个人出牌,怎么让其他玩家立刻看到这个玩家所出的牌。

搜索半天无果,不过倒是发现了这类问题都可以归结为一个问题就是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:

 

ContractedBlock.gif ExpandedBlockStart.gif 查看Board的jsp中的JavaScript
 1    <script type="text/javascript" src="js/AjaxRequest.js">
 2    </script>
 3    <script type="text/javascript" language="javascript">
 4ExpandedBlockStart.gifContractedBlock.gif        function updateInfo() {
 5            var loader = new net.AjaxRequest("updateInfo.action", update, onerror, "POST");
 6        }

 7
 8        window.onload = updateInfo();
 9
10ExpandedBlockStart.gifContractedBlock.gif        function update() {
11            var username = document.createTextNode(this.req.responseText);
12            document.getElementById("userList").appendChild(username);
13            updateInfo();
14        }

15
16ExpandedBlockStart.gifContractedBlock.gif        function onerror() {
17            userList.innerHTML = this.req.responseText;
18        }

19
20ExpandedBlockStart.gifContractedBlock.gif        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
24ExpandedBlockStart.gifContractedBlock.gif        function enterboardComplete() {
25            var loader2 = null;
26        }

27    </script>

 

AjaxRequest.js:

ContractedBlock.gif ExpandedBlockStart.gif AjaxRequest的部分代码
 1var net = new Object();
 2ExpandedBlockStart.gifContractedBlock.gifnet.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
 9ExpandedBlockStart.gifContractedBlock.gifnet.AjaxRequest.prototype.loadDate = function(url, method, params) {
10ExpandedSubBlockStart.gifContractedSubBlock.gif    if (!method) {
11        method = "GET";
12    }

13ExpandedSubBlockStart.gifContractedSubBlock.gif    if (window.XMLHttpRequest) {
14        this.req = new XMLHttpRequest();
15ExpandedSubBlockStart.gifContractedSubBlock.gif    }
 else if (window.ActiveXObject) {
16        this.req = new ActiveXObject("Microsoft.XMLHTTP");
17    }

18ExpandedSubBlockStart.gifContractedSubBlock.gif    if (this.req) {
19ExpandedSubBlockStart.gifContractedSubBlock.gif        try {
20            var loader = this;
21ExpandedSubBlockStart.gifContractedSubBlock.gif            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);
27ExpandedSubBlockStart.gifContractedSubBlock.gif        }
 catch (err) {
28            this.onerror.call(this);
29        }

30    }

31}
;
32
33ExpandedBlockStart.gifContractedBlock.gifnet.AjaxRequest.onReadyState = function() {
34    var req = this.req;
35    var ready = req.readyState;
36ExpandedSubBlockStart.gifContractedSubBlock.gif    if (ready == 4{
37ExpandedSubBlockStart.gifContractedSubBlock.gif        if (req.status == 200{
38            this.onload.call(this);
39ExpandedSubBlockStart.gifContractedSubBlock.gif        }
 else {
40            this.onerror.call(this);
41        }

42    }

43}
;
44
45ExpandedBlockStart.gifContractedBlock.gifnet.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函数,而没有用死循环也是出于这个原因。

在此也希望如果大家有什么更好的方式解决类似问题,请回复一起讨论

 

转载于:https://www.cnblogs.com/ojwftded/archive/2009/11/03/1595543.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值