晚上看到我在silverlight webGame上的导师"深蓝色右手"拿到荣誉,觉得他名至实归。回想自己2010过年来到北京忙于一些琐屑的事情,好久没有动手写我的web传奇了。

去年在群里说我过年要开源我的Web传奇,写一些服务端的文章。后来我发现自己在服务端开发上经验还欠缺,还没有一个成熟的框架,自己也在摸索中,我也打算今年向公司用C++写服务端的同事学下。

在2009年10月份,我就打算写服务端,可我两眼一抹黑,用什么语言写,用什么通讯方式?作为一个6年来一直用C#的人来说,用C#进行开发是个风险比较小的方案。

那么通讯方式呢?siverlight里客户端和服务端通讯有 WCF,RIA Services,Socket,Http。选那一个好呢?我们看以下的场景.

这是令人热血沸腾的传奇3攻城画面,我在上一篇文章所写的攻城战就是这个场面,左下角的旗台也就是当年我誓死捍卫的阵地,想当年我“一夫当关,万夫莫开”,哎,不提当年了。

我们数数这个画面的人物:50个人物,三种职业。有战士在释放“莲月剑法”,有法师在释放“爆裂火焰”,有道士在释放“复活术”。假如你是一个战士,正在用炼狱砍人。那么这个屏幕上的50个人都应该能看到你在砍人,当然说看到时通俗的说法,用专业术语来说是50个客户端同时收到了你砍人的动作数据。这是典型的服务端向客户端推送数据的过程。这一个过程持续时间很短,砍一下人不过1秒左右,为了做到及时性,50个客户端应当在100毫秒以内接收到数据才能保证游戏流畅度.

这样以来,http通讯方式就被排除了,因为http方式服务端是没办法主动发送数据到客户端的,就如同你在浏览器里看网页一样,你请求什么页面,才会得什么内容。打个比方,如果你用http方式来玩游戏的话,你就得不停得刷新浏览器。当然你可能知道页面也能定时自动刷新的,那么这个定时器可是1秒要刷新100次以上。如果50个人都站着不动,那么就算没有数据要发送,服务端却要承受着:50*100=5000次请求/秒。所以我们需要的是服务端能即时得在需要的时候发数据主动发送到客户端。

那么 WCF,RIA Services呢,在很多siverlight程序里都选用了WCF,RIA Services来传递数据,特别是管理系统,siverlight站点.但是做一个webGame是否可行?

WCF是什么?简单介绍下:WCF整合了Remoting和webService等等。而且开发简单(相对的),它既弥补Remoting的只能在.net上运行的缺点,又弥补了asmx只能单向传送消息的缺点。也就是说,WCF是实现跨平台,在跨平台的同时,也可以双向通信.

看来WCF通讯是可行的,但是WCF双工通讯(Duplex channel)又分为基于Http方式和TCP方式的。Http本质上是两对 Request/Response来模拟的,不算真正意义的Duplex channel,效率自然也不高。基于TCP方式的WCF通讯效率较高,也符合OO思想,但是为了追求更高的效率最好也不用它。因为WCF是比较高层的封装,对比更接近底层的Socket通讯,效率不够高。

RIA Services本来就没有一个成熟的正式版本,后来微软也放弃更新了,把它和WCF整合了下,叫WCF RIA Services。

口舌了这么多,其实我想要给大家介绍的重量级人物都等得不耐烦了,让我们请出它来吧:Socket,对,就是它,最早出现在UNIX系统上。后来出现在window系统上也叫做winsocket.这位兄弟在游戏界可是大名鼎鼎,什么“魔兽世界”,“传奇”都得用它。

如何把单机版的SL游戏,变成网络版的?

①.我们需要写一个服务端,和SL客户端之间用Socket通讯

引用命名空间:

 using System.Net.Sockets;
 using System.Net;

我们要新建两个项目:一个服务端使用的SocketServer项目,一个SL客户端使用的SocketClient.

需要注意的是SocketClient是Silverlight类库项目,否则SL客户端无法引用。

②。我们需要一个安全策略文件,在SL3.0里微软为了解决跨域通讯的安全问题,强制要求服务端能提供安全策略文件clientaccesspolicy.xml。

代码

   <?xml version="1.0" encoding ="utf-8"?>
     <access-policy>
        <cross-domain-access>
            <policy>
                <allow-from>
                    <domain uri="*" />
                </allow-from>
                    <grant-to>
                             <socket-resource port="4502-4534" protocol="tcp" />
                             <resource path="/clientbin"/>   
                        </grant-to>
                  </policy>
                </cross-domain-access>
               </access-policy>

这里我们可以看到SL socket通讯使用的是tcp协议,端口限定在4502-4534之间.

clientaccesspolicy.xml需要放在服务端

③服务端在和客户端首次通讯时,客户端会自动向服务端943端口发送安全策略文件的请求。服务端需要把clientaccesspolicy.xml里的内容以byte[]发送给SL客户端

所以我们在启动服务端的时候,需要读取clientaccesspolicy.xml里的内容,同时监听943端口.

启动安全策略文件提供服务

   internal void StartupPolicyServer()
        {
            string policyFile = Path.Combine(Application.StartupPath, "clientaccesspolicy.xml");//读取安全策略文件的内容放入policyBuffer  byte[]中

using (FileStream fs = new FileStream(policyFile, FileMode.Open, FileAccess.Read))
            {
                policyBuffer = new byte[fs.Length];
                fs.Read(policyBuffer, 0, policyBuffer.Length);
            }
            try
            {
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listener.Bind(new IPEndPoint(IPAddress.Any, 943));//监听943端口
                listener.Listen(100);
                listener.BeginAccept(new AsyncCallback(OnClientConnect), null);//当客户端访问943端口时回调OnClientConnect方法
            }
            catch
            { 
            }
        }

//客户端访问943端口时

private readonly string policyRequestString = "<policy-file-request/>";

private void OnClientConnect(IAsyncResult result)
        {

....

requestBuffer = new byte[policyRequestString.Length];

client.BeginReceive(requestBuffer, 0, policyRequestString.Length, SocketFlags.None, new AsyncCallback(OnReceive), client);//接收"<policy-file-request/>"内容长度的byte[]请求。

}

//服务端开始接收客户端的数据

private void OnReceive(IAsyncResult result)
        {
            Socket client = result.AsyncState as Socket;
            try
            {
                received += client.EndReceive(result);//累加接收的字节数目,为了判断是否接收完
                if (received < policyRequestString.Length) //如果"<policy-file-request/>"内容长度的byte[]没有接收完继续接收
                {
                    client.BeginReceive(requestBuffer, received, policyRequestString.Length - received, SocketFlags.None, new AsyncCallback(OnReceive), client);
                    return;
                }
                string request = System.Text.Encoding.UTF8.GetString(requestBuffer, 0, received);
                if (StringComparer.InvariantCultureIgnoreCase.Compare(request, policyRequestString) != 0) //如果客户端在943端口发送的不是"<policy-file-request/>"内容的数据,也就是说请求的不是安全策略文件,就退出函数
                {
                    client.Close();
                    return;
                }
                client.BeginSend(policyBuffer, 0, policyBuffer.Length, SocketFlags.None, new AsyncCallback(OnSend), client);//否则就把安全策略文件的byte[]内容发送给客户端
            }

catch (SocketException)
            {
                client.Close();
            }
        }

④客户端接收到了安全策略文件就能继续在 4502-4534端口之间和服务端进行继续的通讯了,如果服务端没能发送安全策略文件的内容给客户端,则SL客户端会报一个“安全策略”的异常。

由于文章篇幅已经比较长了,到此我们SL客户端和服务端的通讯可以进行,那么服务端和客户端的通讯内容如何约定呢?我们这样把游戏里的各种面向对象的数据以难以肉眼判读的byte[]字节发送到服务端呢?这就想我们把一纸洋洋洒洒的文章用粉碎机弄成纸屑,如果没有高强的法力,我们很难把纸屑还原成纸张.

下一篇文件,我们会探讨下服务端和客户端如何组织通讯内容。Silverlight MMORG WebGame游戏设计(三)-----Server和Client的暗号

上一篇文章:Silverlight MMORG WebGame游戏设计(一)-----一个游戏爱好者的webGame之路

转载于:https://www.cnblogs.com/wangergo/archive/2010/04/07/1706801.html

Silverlight MMORPG WebGame游戏设计(二)--通讯协议之惑相关推荐

  1. Silverlight MMORPG WebGame游戏设计(六)-----Server和Client的婚后协议[附上完整15M游戏DEMO]...

    上回说到Server少爷和Client小姐好不容易踏入婚姻的殿堂,洞房花烛之夜,Client小姐却要Server少爷签下婚后协议.Server一脸不快:"都一家人还签什么协议啊?" ...

  2. Silverlight MMORPG网页游戏开发课程(Game Lesson):目录

    [感谢 银光中国 提供本课程所有源码资源分流] 一次全新的开始,一次全新的构建与诠释.渴望在时空长廊中寻觅传说中光的起源,我决定用这部课程编写一首血脉喷张之进行曲.一年前,我一个人在战斗,前行,引导我 ...

  3. Silverlight MMORPG网页游戏开发课程[一期] 序言

    本课程Demo在线演示地址:http://silverfuture.cn/ (随课程进度不断更新,所有资源暂时放在xap) 2010年7月20日是一个不平凡的日子,应朋友的邀请在自己的家乡广西师范大学 ...

  4. KT148A语音芯片使用说明、硬件设计、通讯协议、常见问题集锦,参考代码

    目录 1.概述 1.1 简介 KT148A是一款32位的DSP语音芯片,标准的SOP8封装.内置420KByte的语音空间,最大支持420秒的语音长度,支持多段语音,同时支持直驱0.5W的扬声器,支持 ...

  5. webgame游戏模式分析二

    分析6类系统到底是做什么. 1.经济系统. 相信大多数开发者都做过电子商务类型的网站吧,要不商店类型的网站做过吧. 再不然,一个产品列表总做过吧. ok,网页游戏中的商店跟一般的网站商店非常类似,而且 ...

  6. Silverlight MMORPG网页游戏开发课程[一期] 第十课:面向对象的重构

    引言 在游戏的基本功能大体实现后适当的回过头来,重新审视当下的游戏框架并做一些有利于下阶段功能延伸的结构改进,以达到精简代码,优化性能,提高拓展性的目的:这就是本节我将要为课程示例游戏做的一次内科大手 ...

  7. Silverlight MMORPG网页游戏开发课程[一期] 第九课:HUD与背景音乐

    引言 征服玩家的不仅仅是创意,无比动人的视觉体验譬如精美的界面UI同样能让人倾慕,辅以优柔的旋律仿若一缕思绪让您身临其境而流连.深刻的第一印象无限大的冲击着玩家那份内敛的狂热,优秀的游戏作品价值将在欢 ...

  8. MMORPG大型游戏设计与开发(part5 of net)

    上一部分将服务器的具体代码的实现介绍给了大家,想必大家也了解到了服务器处理一次消息的复杂度.如果大家能够将各个过程掌握清楚,就会发觉其实整个逻辑与交互过程是比较清晰的.那么服务器与服务器之间的通讯,其 ...

  9. MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

    地图的数据以及区域的信息是场景的重要组成部分,这些数据同时存在客户端和服务器,而且都是由编辑器生成的.那么保存的文件数据结构是怎样的?一张3D的场景地图又是怎样处理这些数据的?同时告诉大家这里同样只是 ...

  10. Silverlight MMORPG网页游戏开发课程[一期] 第十一课:战斗系统之脚本与精灵捕获...

    引言 整个游戏的推进工作显得异常顺利,或许之前我们所做的一切都是为了接下来的核心内容打基础:RPG之战斗系统.在踏入这块神秘而又让人的垂涎的领域前,我们迫切需要充实更多的相关知识以适应并更好的处理即将 ...

最新文章

  1. Java用for循环Map
  2. 信息安全系统设计基础家庭作业
  3. java 基础 --静态
  4. 建立TCP连接时的三次握手与四次挥手问题
  5. Python+Opencv建立一个文档扫描器
  6. java io运用_Java IO相关使用
  7. cocos2dx游戏--欢欢英雄传说--添加攻击按钮
  8. 68张机械原理动图,够你看一晚上了!
  9. 微博html天涯吴奇隆刘诗诗,吴奇隆深夜微博晒爱心,为刘诗诗庆生,网友:撒了一大把狗粮...
  10. CDOJ--1850
  11. 腾讯云推出首款自研服务器星星海;苹果新款Mac Pro整套配齐超30万;Fedora 31稳定版发布|极客头条...
  12. MySql(四):备份与恢复
  13. kafka消息队列学习笔记
  14. mysql 恢复同步_常见MySQL同步错误恢复方法
  15. VBA在Excel中的插件制作
  16. 研发项目wbs分解简单案例_工程项目管理之WBS分解实例(五篇模版)
  17. 201671010447杨露露 实验二词频统计软件项目报告
  18. 短视频剪辑的九大技巧分享
  19. 时间序列分析之GARCH模型介绍与应用
  20. download failed: assets/main/import/09/09f53264-cd95-4751-99ad-d516c164dd80._cconb.dbbin, status: 40

热门文章

  1. 苹果笔记本计算机内存不足怎么办,macbook内存不够用怎么加_苹果电脑增加内存的具体方法...
  2. 马克思主义基本原理概论复习资料
  3. 中国医疗信息化建设“十四五”规划分析及投资前景预测报告2022-2028年版
  4. (BFS/状态压缩)HDU 5025 Saving Tang Monk
  5. 冯诺依曼体系结构及三级缓存
  6. 冯诺依曼体系结构_存算一体:突破冯诺依曼架构瓶颈的希望?
  7. 移动硬盘启动win7蓝屏7b_win7启动蓝屏0X0000007B代码的解决方法
  8. PX PT 磅 EM 以及PS中字间距VA单位的解释
  9. OMNeT++下载、安装及实例tictoc1-tictoc18
  10. SXF-2021软测实习生笔试