队伍成员:梁杰,夏天晗,谢祖三。
周五晚上吃完饭,我们就开始了讨论。
这次的要求是写服务器,客户端以及游戏结果动态显示。很明显是三个部分,我们也就顺其自然, 一人一个部分。我负责服务器,夏天晗负责游戏结果显示,谢祖三负责客户端。
我们使用的语言是Python,Python简洁明了,写起来很流畅。
这次我们并没有像前两次一样大家一起编程,而是分配完任务之后大家分别完成最后再一起测试。主要考虑到实际开发中团队成员不可能每次都在一起开发,所以我们也想模拟一下“分布式开发”,深入感受一下。
虽然是“分布式开发”,但是开始仍然要进行讨论。经过我们的讨论,第5次作业的难点大概有这些:
难点1:服务器和客户端如何通信
服务器和客户端通信是重中之重,如果这个搞不定那后面都不用做了。对于这个问题,我们的主要思路是为客户端和服务器定义一套命令规则,比如客户端发送的数据如果以“check”开头,服务器就会返回当前的状态;如果以“sign”开头,服务器就会注册用户。同样,客户端也会根据服务器返回的数据执行不同的操作。
难点2:服务器和展示页面如何通信
这个也是一个大问题,我们参考了其他开发教程中服务器和页面的开发模式,最后决定采用数据接口来解决。数据接口就是说服务器和页面约定好一种数据格式,然后当页面访问服务器时,服务器就按照约定好的格式返回数据,页面再进行解析并显示。
难点3:如何应对多客户端
我们想做的是真正实用的服务器,所以只能处理单客户端是肯定不够的。对于多客户端,最直接的思路就是多线程。由于Python对多线程的支持非常好,我们实现起来也不是特别难。
难点4:大家如何协同开发
这是我们关注的一个重点,也是我们希望学到东西的一个环节。讨论完之后就进入开发阶段,大家如何在身处不同地方的情况下协同开发,我们并没有一个成熟的方案。不过经过我们的讨论,最后还是决定采用“同时开发”,“连环组合”,“统一测试”的方案。“同时开发”是指分配完任务之后大家同时完成自己的任务;“连环组合”是指大家完成自己的任务之后,一环一环进行组合,首先是客户端服务器组合,然后是服务器页面组合,确保出现问题可以第一时间定位;“统一测试”是指组合完成并成功运行之后,大家一起进行测试,看看在多机情况下是否可以正常运行。
由于这次是分布式开发,所以每个人对其他人的开发过程并不是很了解,只记录自己的开发过程。
我开发的是服务器,主要使用的是Python的thread和socket两个库。因为自己之前没有写过服务器,所以从网上找了很多资料来学习如何使用Python编写服务器。看了很多教程之后慢慢有了头绪,按照示例代码来一点一点修改,自己的服务器雏形就出来了。
然后根据上面提到的几个难点,分别实现了多线程、命名规则和数据接口,接下来就是“连环组合”部分了。
组合并没有出问题,但是谢祖三的一句提醒让我发现了一个很严重的问题:作业要求并没有完全满足。因为之前开发时候只考虑服务器的核心功能了,并没有考虑诸如两种游戏模式、用户名重复、防DDOS等要求。发现问题之后我马上进行修改,虽然过程中出了一些小问题,但是最后还是成功搞定!
最后统一测试的时候也不像我们想象的那么顺利。本来我们考虑用路由器,但是连上路由之后发现互相都无法ping通,更不用说玩游戏了。后来折腾了半天,用网线互联搞定了。还得感谢谢祖三同学带了一根网线过来……
采用人工测试。
首先开启服务端:
$ python goldserver.py 1
可以看到服务器开启成功,正在等待客户端连接。
1是指第一种游戏类型,也就是每个用户提交1个数字。如果参数改成2就是第二种游戏类型。
这里说明一下,游戏进行中也是可以连接服务器的,但是这样的话新连接的客户端成绩是0,对于其他客户端来说可能不太公平,所以我们留了一段时间来让所有客户端连接服务器,然后统一开始游戏。
然后我们运行自动连接脚本,将所有客户端连接到服务器:
$ python auto_play.py
我们可以看到有大量客户端连接到了服务器:
然后稍等一会,游戏就开始了:
可以看到服务器会输出游戏轮数,每轮黄金点。
然后我们来看看页面展示,打开result.html,可以看到上面是动态黄金点的表:
这个表会随着游戏进行自动更新。
页面下方是动态用户排名:
同样会自动更新。
这是我们第三次结对编程,这次并没有采用之前的一起编程的方式,而是创新的采用了一种“分布式编程”的方式来完成作业。虽然大家实际开发中遇到了很多没有想到的问题,但是通过我们的努力,所有的问题都被克服了。总的来说,这次的作业完成的比较满意,老师的要求也全部达到了。
这里单独把独特之处列出来,方便大家查看。
多线程:
多线程是处理高并发客户端的利器,如果没有多线程很难保证在较短的游戏时间内处理所有用户请求。
命令规则:
命令规则是指客户端和服务器之间通信的标准。我们采用的主要是类命令的格式,所以叫做命令规则。例如:sign username password 就是注册用户的命令,play username password 34 就是参与游戏的命令。这种方式简单有效,便于开发。
数据接口:
数据接口主要是处理服务器和页面间的通信。我们约定的数据类型是json格式,也就是说每当页面向服务器请求数据时,服务器会将所有黄金点以及当前用户排名封装成json格式数据返回给页面,然后页面解析json数据并进行更新。
动态更新:
动态更新主要是在页面内部使用js来进行高频访问,从而保证随服务器的游戏进程动态更新黄金点和用户排名。
Personal Software Process Stages |
时间百分比(%) |
实际花费的时间 (分钟) |
原来估计的时间 (分钟) |
计划 |
10% | 36 | 24 |
· 估计这个任务需要多少时间,把工作细化并大致排序 |
10% | 36 | 24 |
开发 |
85% | 306 | 204 |
· 需求分析 (包括学习新技术) |
15% | 54 | 36 |
· 设计复审 (和同事审核设计文档) |
10% | 36 | 24 |
· 代码规范 (制定合适的规范) |
5% | 18 | 12 |
· 具体设计 |
10% | 36 | 24 |
· 具体编码 |
35% | 126 | 84 |
· 代码复审 |
5% | 18 | 12 |
· 测试(自我测试,修改代码,提交修改) |
5% | 18 | 12 |
总结报告 |
5% | 18 | 12 |
总计 | 100% | 总用时 360 |
总估计的用时 240 |