精华内容
下载资源
问答
  • 无论是哪种三层架构方式,只要对数据包进行压缩,必须找出个压缩率与时间之比的最佳方式。RO是用Zlib压缩数据流,Zlib最新版本为1.2.3,RO也使用了最新了版本。我个人认为,在服务端,压缩时间比压缩率重要的多,...

    无论是哪种三层架构方式,只要对数据包进行压缩,必须找出一个压缩率与时间之比的最佳方式。

    RO是用Zlib压缩数据流,Zlib最新版本为1.2.3,RO也使用了最新了版本。

    我个人认为,在服务端,压缩时间比压缩率重要的多,特别是在并发数特别多的服务端,这点尤其为重要。

    解压缩就快多了,甚至只有压缩时间的百分之一左右。

    ZCompressStream的clDefault压缩率仅比clFastest压缩率的压缩体积仅减少了10%左右。

    下面是我们实践测试:

    在uROBinMessage单元里找到以下方法:

    ZCompressStream(Source, Destination);

    改为:

    ZCompressStream(Source, Destination,clFastest);

    重新编译,测试,在数据库里下载一个2M的BMP文件到客户端,采用clFastest的压缩方式比采用默认的方式快20%-30%。

    千万别小看2M左右的数据流,如果仅仅是普通的文本+数值,数据量都上万数量级甚至是十万数量级了。

    你可能还会这样异想天开,要是几百兆甚至是上G呢?

    对不起,没有任何一个中间层(查询数据库方式)允许你下载一个这么大的数据流,光是压缩这么大的数据流,在高并发请求下,肯定不堪重负。如果非要有这样的需求,建议你在三层加一个FTP接口下载文件,对应传输大文件,FTP优于TCP。

    展开全文
  • RO经济系统分析

    千次阅读 2006-07-29 00:07:00
    RO经济系统分析RO的经济系统没有太大的漏洞。货币供应增长速度与道具物品的积累速度基本同步,从而能够保持比较稳定的流通率,物价一般不会出现剧烈波动,用户的日常经济活动具有基本保障;道具物品和货币均有一定的...
    RO经济系统分析
    

    RO的经济系统没有太大的漏洞。货币供应增长速度与道具物品的积累速度基本同步,从而能够保持比较稳定的流通率,物价一般不会出现剧烈波动,用户的日常经济活动具有基本保障;道具物品和货币均有一定的回收机制,具备有限的通货紧缩与通货膨胀自我调节能力;创见性的露天商店系统对整个经济系统的流通能力和自我平衡能力的具有一定的强化作用。但整个经济系统还不够完善,没有严密的货币供应控制机制,没有交易撮合和交易代理机制,没有融投资机制,导致经济系统活力不足,没能完全发挥应有的作用。

    一、货币的供应、回笼和平衡

    货币的唯一供应机制依靠NPC,玩家将怪物掉落的物品卖给NPC,获得ROB。
    货币的唯一回笼机制也依靠NPC,玩家使用ROB从NPC处购买必须的消耗品。

    RO里有两套货币平衡机制:

    1、通过怪物掉物品来控制,经验高的怪一般不掉值钱物品,掉值钱物品的怪经验一般很低。所以玩家如果想快速发展角色能力,专注于打经验型的怪,就会消耗大于收获,属于消费行为;如果玩家希望积累金钱,就必须专注于打经济型的怪,就会收获大于消耗,属于生产行为。

    2、通过角色能力的分化来控制,打怪能力强的人物配点,PK能力会很弱,而PK能力强的人物配点,打怪能力会很弱,而且即使专门PK的角色,在PK过程中的道具消耗也非常大。所以玩家对游戏有了一定程度的了解之后,通常会使用多个角色,某些角色专职打怪生产,某些角色专职PK消费。

    由于玩家的消耗不仅仅发生在打怪升级过程当中,RO的玩家对战体系和现代战争一样,拼的其实是经济,日常PK、每周两次的攻城战都会发生大规模的消耗,最典型的例子,铁匠这一职业最具威力的技能是“金钱投掷”,直接就是扔钱如流水。所以在RO中,ROB的紧缺程度一直相当高。

    这种“消费才能娱乐”的经济模式,具有较强的自我平衡能力,整体消费过头了,必然会导ROB紧缺,就会有人负担不起,停止消费去积极生产;整体生产过剩了,必然会导致ROB充裕,助长玩家骄奢之情,消费活动就会频繁激烈。

    这样的经济系统促成了玩家的分化:部分玩家转化成了职业生产者,他们专练各种赚钱机器,向其他玩家出售ROB;部分玩家转化成了纯粹的消费者,他们专练杀人机器,直接购买ROB,然后到PK场、攻城战大显身手。另外,专业生产者的出现,保障了ROB的总供应量略大于总回笼量,ROB总流通量的适量增长对于玩家间道具交易行为的活跃具有重要意义。

    前面已经提到,这种经济模式必然引起玩家的分化,就必然需要大量的点卡/虚拟货币交易做支撑,但是RO没有提供官方的点卡/虚拟货币交易系统,导致玩家相互欺诈事件大量发生,严重影响了整个虚拟社会的和谐。很多玩家因为受骗而对游戏感到失望从而退出游戏,运营商却一直无动于衷,显然运营商对游戏经济系统的特点认识是不足的。


    二、资产的积累、提升和流通

    由于怪物掉落的一般性物品以及消耗品的价格是由NPC固定死的,它们实际上等同于货币,不可视作资产。所以在游戏中,只有稀有物品——装备和饰品可以视为资产。

    装备有两个来源,绝大部分来自于怪物的偶尔掉落,掉落率通常为万分之一;顶级装备来源于攻城战奖励,数量更加稀少。饰品也有两个来源,绝大部分由苛刻的道具收集制作任务产生,偶尔由线上活动派发。

    装备既可以看作生产资料,它影响到角色的能力,也可以看作奢侈品,它可以拿来炫耀;饰品是纯粹的奢侈品,唯一的用途就是炫耀。所以装备是更完整意义上的资产,更具代表性。以下的分析,仅仅以装备作为研究对象。

    装备除了具备初始属性,还可以通过“精炼”来提升攻击力或防御力,精炼不仅仅要消耗金钱,还具备很大的风险,一旦精炼失败,装备就会消失。一件装备可以精炼10次,每次都有较大的概率失败,最终成功达到“+10”的概率是千分之一左右。

    因此,游戏中资产积累的限度可以非常大,全身+10装备的角色,相当于积累了数千件甚至上万件装备,也就是要杀上亿只怪才能达成,依靠一个角色单独的力量,需要积累数十年的时间。也就是说,游戏中资产积累的速度还是比较合理的,从公测到现在1年半时间,RO玩家主力号的装备普遍在+7、+8左右,离+10还有很大的距离。

    装备的提升是纯粹的概率事件,与角色的属性没有任何关联,也没有任何技巧可言,所以提升装备既不可能成为一种可靠的牟利手段,也不会影响到整个经济体系的平衡。然而正像现实生活中难免有人沉迷于赌博一样,RO中的精炼也吸引了大量的赌徒放手一搏。幸运儿可能一夜暴富,但倾家荡产者也比比皆是,这种局面靠什么来了结?幸运儿如何兑现他的幸运?倒霉鬼如何继续他的游戏生涯?还是需要点卡/虚拟货币交易系统,甚至是虚拟物品/现实货币交易系统来支撑。

    因为装备的掉落率固定,所以资产的积累速度基本上是恒定的。所以装备的价格必然受ROB总流通量的影响,精炼在很大程度上保障了物价体系的稳定:当物价低迷的时候,大量的装备由于惜售而被拿去精炼消失了,一方面,减轻了资产流通的压力,另一方面却造成高级装备的数量可能上升。当然,高级装备由于数量非常稀少,通常都超出了ROB交易的范围而直接使用RMB交易,从而不会造成新的因ROB流通不足而产生的资产流通障碍,但是整个经济系统对虚拟物品/现实货币交易系统的依赖度会进一步上升。

    可见,RO中经济系统的平衡难以独立完成,它需要虚拟/现实交易系统来进行支撑。而运营商在此方面的态度生硬,不仅没有任何“便民措施”出台,甚至对玩家在自发进行的交易中出现问题时,推卸责任,不闻不问,窃以为是愚蠢的做法。

    三、金融机构的设置

    RO在提供最原始的一对一交易手段的同时,增设了露天商店系统,玩家可以随时随地摆摊开店,实现一对多交易,也算初步进入了商业社会。但是,贸易形式依然过于单一,限制了整个经济系统的活力。

    首先,缺乏交易撮合机制,玩家之间的供求信息只能通过刷屏来传递,效率非常低;或者通过游戏外的第三方论坛,效率也很低。

    其次,摆摊开店需要亲自蹲点,没有代理机制,很不方便。开店行为完全可以用NPC来完成,最简单的做法是派宠物去摆摊,RO里的宠物不会帮主人战斗也就罢了,守守地摊都不会,玩家养宠物干嘛?更完善的做法是设置专门的NPC,例如交易市场,卖家直接将需出售物品价格、数量提交给交易市场代管,卖出则ROB直接转到卖家账户,一定期限内没卖出则转入卖家仓库;买家可集中分类排序查阅代卖物品,选择自己需要的物品。这样就形成了多对多的更先进的,效率更高的贸易形式。

    金融机构方面,RO更是极度匮乏。首先,没有中央银行,没有严密的货币供应回笼机制;其次,没有融投资机构,玩家缺钱用的时候不得不将仓库里的物品卖给NPC,而等以后需要这些物品的时候却不能从NPC处买回来,只能再去打怪。其实完全可以设置当铺解决玩家融资问题,或者更完善一点,设置投资银行,让有闲钱的玩家可以投资,暂时缺钱的玩家则可以用仓库抵押贷款,这样还能顺便避免玩家之间私下借贷产生的欺诈和纠纷。

    总之,RO的经济系统在金融机构的设置上还十分原始,运营商也没有改善的意图,运营商对用户需求的研究还仅仅停留在游戏内容上,对网络游戏的社会性特质认识严重不足。 
    展开全文
  • RO38 –比较RemObjects SDK 通道

    千次阅读 2008-04-17 11:26:00
    RO38 –比较RemObjects SDK 通道 本文汇总了RemObjects SDK提供的通道: 最通用的通道 1) HTTP 通道:使用www超文本传输协议的灵活,网络无关的通信. 2) Super TCP 通道: 在客户端服务端灵活通用的双向传输
      
    
    RO38 – 比较 RemObjects SDK 通道                                  
    本文汇总了 RemObjects SDK 提供的通道 :
    • 最通用的通道
      • 1) HTTP 通道:使用www超文本传输协议的灵活,网络无关的通信.
      • 2) Super TCP 通道: 在客户端服务端灵活通用的双向传输.
      • 3) Super HTTP 通道- new in 'Vinci'
    • 常用的通道Frequently used channels
      • 4) 以前的TCP通道: 通过TCP实现轻量级通信.
      • 5) Email 通道(Delphi): 与存在的Email组织异步通讯.
      • 6) Local 通道:直接应用程序内部通信.
      • 7) DLL 通道(Delphi): DLL中执行服务端逻辑,并通过标准的RemObjects SDK接口调用机制调用.
    • 很少使用的通道
      • 8) UDP and Broadcast 通道(Delphi): 轻量数据包通信.
      • 9) Named Pipe 通道:不使用TCP/IP的局域网内部的通信.
      • 10) WinMessage 通信(Delphi): 本机中的内部过程通信.
     
    1) HTTP 通道
    最常用的通道可能是基于超文本传输协议的 . HTTP 协议 , 组成 www 的基础 , Internet 中最常用的协议之一 , RemObjects SDK 中使用可以提供各种好处 :
    • 由于HTTP的广泛使用,这种协议可以在轻松用于受限的网络环境,如有防火墙或使用代理将客户端与Internet隔离. 如果终端用户可以通过浏览器访问网络,基于HTTP通道的客户端也非常可能运行.
    • 服务端地址使用标准的URL标识,这样用户可以轻松明确的处理地址.
    • 如果希望,HTTP通道可以提供人们能直接读取的服务端信息和开放的服务信息,并可以通过web浏览器查看.
    总之 ,HTTP 是当你位于扩展站点而无法控制网络时最好的协议 , 可以使你的客户端轻松的在各种类型的网络中工作 .
    两种版本 (Delphi .NET) 中都提供了 HTTP 客户端和服务端通道的几种实现 , 至于那种最好这取决于用户的偏爱和体会 . 所有的 HTTP 客户端都可以连接到 HTTP 服务端 , 反之亦然 .
    值得一说的是基于 WinINET 的客户端通道 (Delphi .NET) 可以使用 IE 浏览器的设置 , 包括使用代理和自动拨号规则 , 然而 Indy Internet 数据包通道将使用实现于原始 TCP 之上的 HTTP.
    对于 Delphi,BPDX 服务通道提供了最好的性能和灵活性 , 但是这比轻量的 Indy 服务通道需要更多的资源 .
    客户端通道组件 :
    • IpHttpClientChannel (.NET)
    • WinInetHttpClientChannel (.NET)
    • TROIndyHttpChannel (Delphi)
    • TROWinInetHTTPChannel (Delphi)
    • TROSynapseHTTPChannel (Delphi)
    服务端通道组件 :
    • IpHttpServerChannel (.NET)
    • HttpSysServerChannel (.NET)- new in 'Vinci' (see note)
    • WebProcessor (ASP.NET)
    • TROIndyHTTPServer (Delphi)
    • TROBPDXHttpServer (Delphi)
    • TROWebBrokerServer (Delphi)
     
    注意 :
    HttpSysServerChannel
    使用从 IIS 共享的微软 HTTP 内核 , 这样允许 standalone 服务从 IIS web 服务中分派一个端口 .
    2) Super TCP 通道
    Super TCP 通道组件提供实用灵活的通信通道 , 使用永久连接实现真正的异步通讯和服务回调 .
    在原始的 TCP 连接之上改进的客户自定义协议 , 这个通道允许使用传统通道类型所没有的高级特性 :
    • 保持实时连接,通过灵活的PING/PONG系统发现断开的连接(如由于网络繁忙)并无缝修复.
    • 结合服务端和客户端通信,可以使服务端向客户端主动的发送事件或异步响应,而不用去轮询,减少了网络流量提高了回调的效率.
    • 允许使用单通道同时发送多个请求.
    这个通道广泛的用于需要事件和服务回调的情形 , 而且有防火墙和代理服务时也不要求使用基于 HTTP 的通道 .
    客户端通道组件 :
    • SuperTcpClientChannel (.NET)
    • TROSuperTcpChannel (Delphi)
    服务端通道组件 :
    • SuperTcpServerChannel (.NET)
    • TROSuperTcpServer (Delphi)
     
    3) Super HTTP 通道 - new in 'Vinci'
    这个通道如 Super TCP 通道一样提供了双向通信 , 但是它基于 HTTP, 从而可以穿透防火墙和精确的代理 . 它比 Super TCP 通道的代价稍高一些 , 因为要在服务端使用两条连接 .
    客户端通道组件 :
    • IpSuperHttpClientChannel (.NET)
    • WinInetSuperHttpClientChannel (.NET)
    • TROIndySuperHttpChannel (Delphi)
    • TROSynapseSuperHttpChannel (Delphi)
    服务端通道组件 :
    • IpSuperHttpServerChannel (.NET)
    • HttpSysSuperHttpServerChannel (.NET)
    • SuperHttpWebProcessor (ASP.NET)
    • TROIpSuperHttpServer (Delphi)
     
    4) 过期的 TCP 通道
    TCP, 一种传输控制协议 , 是两种基于底层的使用 TCP/IP 网络堆栈的 Internet 通讯基本协议之一 , 在客户端和服务端通过连接提供数据传输 . 然而 TCP 也为更复杂的传输协议 ( HTTP,POP3 ) 提供支持 ,TCP 通道使用原始的 TCP 提供轻量协议 , 在传输消息中没有添加任何附加信息 .
    当网络流量小并且没有使用防火墙时 TCP 通道是最好的选择 . 这时 TCP 通道可以提供方法调用的最好执行效率 .
    Delphi ,BPDX 服务通道提供了最好的效率和高灵活行 , 但是要比轻量 Indy 服务通道需要更多的资源 .
    客户端通道组件 :
    • IpTcpClientChannel (.NET)
    • TROIndyTcpChannel (Delphi)
    服务端通道组件 :
    • IpTcpServerChannel (.NET)
    • TROIndyTcpServer (Delphi)
    • TROBPDXTcpServer (Delphi)
     
    5) Email 通道 (Delphi)
    Email 通道使用标准的 Email 和存在的 POP3 SMTP 服务执行异步通讯 , 向服务端发送请求并接收响应 .
    客户端通道指定 Email 地址 , 并使用这个地址向服务端发送处理请求 . 服务端从 POP3 信箱中接收到邮件 , 处理请求 , 最后也使用 Email 的形式向客户端返回处理结果 . 客户端通道通过轮询其 POP3 信箱接收响应 .
    这个通道适用于长时间执行 ( 可能会超过单个客户端 Session 的有效时间 OutTime) 的请求 . 由于请求和响应在 POP3 信箱中是持续的 , 客户端发送请求后退出 , 而接收响应可能要在几小时或几天以后 . 同样 , 请求发送到服务端可能不会马上执行 - 服务端启动后将从其邮件箱中提取并处理邮件 .
    客户端通道组件 :
    • TROEmailChannel (Delphi)
    服务端通道组件 :
    • TROEmailServer (Delphi)
     
    6) Local 通道
    Local 通道允许 RemObjects SDK .NET Delphi 应用程序中基于单机通讯 ; 使你可以轻松重用集成的客户端和服务端应用程序 , 或建立单层应用程序稍后可以简单的修改通道类型移为他用 .
    关于第一方面将应用程序逻辑分为客户端和服务器然后又要在同一个执行文件中使用看起来可能没什么用处 , 这个通道在如下两种情形时很有帮助 , 特别是当结合 Data Abstract 数据库多层架构 :
    • 在保留扩充性的前提下实现一个单层应用程序,在需要的时候可以很容易的升级为三层解决方案.
    • 将多层应用重用与单层环境-如出售单用户版本的产品,提供一个桌面版的客户机/服务器数据库前端.
    在这两个案例或相似的情况下 ,Local 通道可以简单的将客户端和服务端组合在一个应用程序中 , 但是仍然保留了逻辑上的多层次分离 .
    客户端通道组件 :
    • LocalClientChannel (.NET)
    • TROLocalChannel (Delphi)
    服务端通道组件 :
    • LocalServerChannel (.NET)
    • TROLocalServer (Delphi)
     
    7) DLL 通道 (Delphi)
    DLL 通道允许你在 DLL 内部执行服务逻辑 , 其使用标准的 RemObjects SDK 调用机制 . 通道自动为你的客户端过程加载 DLL, 并像远程服务一样将服务端方法开放出来 .
    为什么要使用这个通道请查看上面的 Local 通道小节 .
    客户端通道组件 :
    • TRODLLChannel (Delphi)
    服务端通道组件 :
    • TROLocalServer (Delphi)
     
    8) UDP Broadcast 通道 (Delphi)
    除了 TCP, UDP 是另外一个 Internet TCP/IP 网络组织的基本传输协议 . TCP 相比 ,UDP 没有基于连接传输数据的概念 , 而是在网络中发送单独的数据包 - 可寻址数据包 .
    UDP 也提供了没有错误修正和保证的传递方式 , 所以通过 UDP 发送的数据包可能会并没有达到目的地而丢失 , 或发生错误而简单的放弃 . 同时 UPD 通过自动截取而不提供大数据包的传递 . 总之 ,UDP TCP 相比更快更有效率 .
    你可能想在需要高频率高效率传递小数据包事使用基于 UDP 的通道 , 而且不用去考虑网络错误调整和包恢复 ( TCP 提供的特性 ). 这只能用于局域网的情形 , 网络组织可靠并且发生丢包的情况非常少 .
    Broadcast 通道与 UDP 通道变化而来 , 允许你向本地网络中所有可用的服务端使用 UDP 广播发送请求 . 这在通知或搜索可用服务端时非常有用 .
    这两种通道可以用于异步模式 ; 对于广播的情形 , 你的服务端将调用 ROSendNoResponse 防止任何响应形式发送 ( 以便于大量的接收方可以取消消息通知 ), 直到你的客户端将准备好接收多个响应 .
    客户端通道组件 :
    • TROIndyUdpChannel (Delphi)
    • TROBroadcastChannel (Delphi)
    服务端通道组件 :
    • TROIndyUdpServer (Delphi)
    • TROBroadcastServer (Delphi)
    9) Named Pipe 通道
    这个通道使用 Windows 的命名管道特性在客户端和服务端通讯 . 推荐使用命名管道在单机的不同进程直接通讯 , 尤其是在不同用户环境下运行 . 这很有用 , 例如对服务的控制 .
    请订阅平台 SDK MSDN 文档查看更多命名管道信息 .
    提示 : 牢记一个要点 : Windows 设置了同时连接到一个命名管道的客户端数量 -Home 版为 5 ,Pro 版为 10 . 如果要运行一个网络服务 TCP/IP 是最好的选择 .
    客户端通道组件 :
    • NamedPipeClientChannel (.NET) - new in 'Vinci'
    • TRONamedPipeChannel (Delphi)
    服务端通道组件 :
    • NamedPipeServerChannel (.NET) - new in 'Vinci'
    • TRONamedPipeServer (Delphi)
     
    10) WinMessage 通道 (Delphi)
    这个通道使用 Windows 消息在客户端和服务端通讯 .
    这是在单机内部进程间通讯的一个简单方式 ,Windows 消息有一些限制 - 不能在 Windows 服务 ( Exe 文件对应 ) 中与服务 (Service) 通讯 , 使用 Windows 消息 (MSMQ) 轮询来实现客户端和服务端通讯 . 请订阅平台 SDK MSDN 文档查看这个概念的更多信息 .
    客户端通道组件 :
    • TROWinMessageChannel (Delphi)
    服务端通道组件 :
    • TROWinMessageServer (Delphi)
     
    结论
    本文比较了各种通道然后使用他们 , 如果你在使用时有什么问题请发送 Email support@remobjects.com 联系 .
     
    展开全文
  • RO27 - RemObjects 3.0 SDK 综述

    千次阅读 2008-04-15 12:03:00
    RO27 - RemObjects 3.0 SDK 综述 RemObjects SDK 3.0 简介中我们看到了他的新特性和工具,这些都可以给我们开发方式带来很大的改进. 这篇文档我们看看关于产品的概况和令人兴奋的新特性. Service Tester 用处分布式...
      
    
    RO27 - RemObjects 3.0 SDK 综述
    RemObjects SDK 3.0 简介中我们看到了他的新特性和工具 , 这些都可以给我们开发方式带来很大的改进 . 这篇文档我们看看关于产品的概况和令人兴奋的新特性 .
    Service Tester 用处
    分布式系统提供的灵活性和适用性是传统的 CS 结构无法比拟的 . 但是开发和测试分布式系统通常复杂费时 . 在基于服务的客户端程序开发中我们只是调试本程序还是不够的 , 还有大量的交互式请求和特定的服务过程大量触发的效率等 .
    一般的测试方案产生出脚本并测试最终用户应用 , 但不能做到真正的模拟大量用户来代理远程服务器或使用一些 RemObjects 特性 .
    这样你可以自己写测试应用程序或使用像 DUnit 的测试工具 , 但是还要有很多工作要作 .
    RemObjects 服务测试 (ROST) 可以解决这些问题 . 为每个服务方法产生测试脚本并使用多线程并发调用这些方法 . 测试完成 ROST 提供测试图解 , 其他的事物 , 每秒钟请求数量 , 网络传输情况等信息 . 测试脚本可以保存 , 你修改了远程服务方法后可以再次运行查看修改后对系统效率和功能改善 .
    ROST 支持所有数据类型 : 简单数量类型 , 复杂的结构体 , 二进制流和数组 . 通过直观的界面可以输入测试函数的参数并观测最终执行结果 .
    下面的截图可以看到如何启动 ROST 来执行 MegaDemo 中的 EchoPerson 方法 :
    下面的截图是测试正在进行时的情况 :
    ROST 经配置后使用 RemObjects SDK 提供的所有通道 (channels) 和消息 (message).
    下面的截图显示连接配置对话框 :
    ROST 是一个很有价值的好帮手 , 使用它可以在测试评估你的应用程序服务器时节省大量时间 . 这完全是 RAD 操作 !
    客户端均衡负载和容错处理
    RemObjects SDK 的设计目标是成为一个可升级系统 .
    默认的 ,RemObjects 不指定固定连接 , 我们不用写代码就可以实现连接单个服务器或多个服务器 . Cisco 范例中 , Windows 网路均衡负载 , F5 Networks hardware, 和其他硬件软件都与 RO-based 系统无缝的集成在一起 .
    RemObjects 3.0 的传输通道已经升级支持客户端的均衡负载和容错 . 本质上你可以为你的通道的 TROServerLocator 属性明确的提供一系列的服务器列表 . 你可以控制通道的均衡负载请求,或在当前服务器故障时选择另外一个 . 通道可以寻找服务并自动发现在线的服务器 , 但如果要尝试搜寻所有可能的目的源时很能会报异常 .
    下面的截图是在 TROWinINetHTTPChannel 中设置属性 :
    下面的截图展示了独立的 TROServerLocator 列表 :
    最后 , 这个截图显示测试应用程序的两个服务器通过连接和断开模拟断线条件输出的结果 :
    COM Active 脚本支持
    虽然 RemObjects 服务器可以连接任何操作系统和客户端 (Windows, Linux, Pocket PCs, .Net, Mono, 和其他用 ANSI-C 编译的程序 ), 但在 Windows 系统下 ,COM 几乎成了标准的用法 . 一些应用程序像 Excel, Word, Lotus Notes 可以通过 OLE 操纵 , 有的高级用户可以用 VBScript 脚本控制它们 . Web 开发中 ,ASP Web 页面经常使用相似及的技术操作 COM 对象 (VBScript JavaScript).
    RemObjects 3.0 使用 COM DLL 规则 , 这样可以使一种语言能使用不同的 RemObjects 服务器 . RemObjects SDK 3.0 生成的 COM library 发布的库如下 :
    ROServer.CreateService 方法用服务方法名作参数返回一个对象可以将 COM 方法调用转换为 RemObjects 调用 ( 二进制流或 Soap).
    通过使用 ChannelType MessageType 属性 ( 都是字符串 ), 你可以确定组件的类型 , TROBINMessage TROWinINetHTTPChannel, 与服务器通信 .
    通过使用 SetXXXProperty ReadXXXProperty 方法你可以自定义属性 , 例如 TargetURL 或自定义压缩 .
    下面的截图展示了 Excel 电子表格调用 MegaDemo 服务器的 Sum 方法 :
    与按钮相关的代码如下 :
    Private Sub CommandButton1_Click()
     Dim result
     Set ROServer = CreateObject("RemObjects.COMServer")
     ROServer.MessageType = "TROBINMessage"
     ROServer.ChannelType = "TROWinInetHTTPChannel"
     ROServer.SetChannelProperty "TargetURL", http://localhost:8099/BIN
     Set MegaDemoService = ROServer.CreateService("NewService")
     Dim A, B
     A = Sheets("Sheet1").Cells(9, 4).Value
     B = Sheets("Sheet1").Cells(10, 4).Value
     result = MegaDemoService.Sum(A, B)
     MsgBox "Sum " & A & "+" & B & "=" & result
     Set MegaDemoService = Nothing
     Set ROServer = Nothing
    End Sub
    下面的截图展示了 ASP 页面向用户显示简单信息 :
    代码如下 :
    <%
    Dim result
     
    Set ROServer = Server.CreateObject("RemObjects.COMServer")
    ROServer.MessageType = "TROBINMessage"
    ROServer.ChannelType = "TROWinInetHTTPChannel"
    ROServer.SetChannelProperty "TargetURL", "http://localhost:8099/BIN"
     
    Set MegaDemoService = ROServer.CreateService("NewService")
     
    Response.Write "<STRONG>This is an ASP page that invokes methods "
    Response.Write "of the RemObjects MegaDemo</STRONG><BR><BR>"
     
    result = MegaDemoService.Sum(100, 200)
    Response.Write "The result of 100+200 is " & result & "<BR>"
     
    result = MegaDemoService.GetServerTime
    Response.Write "The time on the server is " & result
     
    Set MegaDemoService = nothing
    Set ROServer = nothing
    %>
    广播服务事件 服务器端
    广播服务事件是 RemObjects3.0 新特性 , 运行服务器异步执行客户端的回调函数 . 回调函数是在客户端定义而由服务器相应一个事件时调用 .
    假设一个聊天程序 , 当一个用户类型信息被中心服务器接受后 , 再转发到其他所有的用户 . 为了发送消息 , 服务器端需要调用客户端事件句柄 ( OnSendMessage 方法 ). 只有当服务器能通过客户端的 IP 与其交互 , 或客户端在服务器回调中是启动的 , 才能完整这个功能 .
    RemObjects SDK 2.0 中可以让应用程序的客户端和服务器端同时调用我们描述的回调函数 , 但是这只限于局域网 ( 由于网路地址转换的问题 );
    下图是解释 :
    当客户端 1 发送一个消息 , 由于服务器知道客户端 2 的直接 IP 地址 (192.168.0.101) 可以将其发送到客户端 2. 而客户端 3 4 是不能到达的 , 因为使用了共享 IP 地址 (24.100.3.36) 与聊天程序服务器相连 . 事实上不同局域网要共享相同的 IP 地址增加了其他的复杂性 . 网络中的设备像网关 , 防火墙给整个问题带来了更大的复杂性 .
    通常 , 写不可升级和多网络碎片的分布式系统回调可以避免 . 要使你的系统支持升级并让客户端接受远程通知的唯一解决方法就是使用基于客户端轮询和服务器队列的通道 . 而这就是广播服务器事件提供的 .
    RemObjects 3 服务器可以将客户端定时发送的消息存储在队列中 , 如下图 :
    当客户端接受一个消息 , 他们将调用特定的事件处理程序 ( Delphi 的事件规则相同 ).
    这个基于 RemObjects3.0 的聊天程序展示了如何生成用户连接一个或多个服务器上的程序 . 这个例子可以让系统管理员远程断开客户端或适时的向客户端发送系统消息 .
    下面的截图展示了两个客户聊天的 Session, 收到了一个服务器要重新启动的消息 .
    RemObjects 3.0 中这种功能很好实现 . 服务器端我们定义了一个 ChatService 服务 :
    IChatService = interface
     ['{6893042C-3354-4AE6-B5FA-E7A637475C30}']
     procedure Login(const UserID: String);
     procedure Logout;
     procedure SendMessage(const MessageText: String);
    end;
    下面截图展示 Service Builder:
    这个例子的目标是当一个方法被调用将在每个客户端抛出特定的事件 . RemObjects 3.0 中等以事件使用新类型 "Callback Sink" [ 这个名字将在发布版本中改变 ].
    聊天服务程序包含 2 callback sinks 例子 : ChatEvents (OnLogin, OnLogout, OnSendMessage)( 当其他客户端有操作时客户端接收 ) ChatServerEvents (OnSystemShutdown, OnMandatoryClose)( 系统管理员向客户端发送消息 ).
    下图展示了如何在 Service Builder 定义 ChatEvents:
    RemObjects 预处理程序可以自动生成代码和 callback sinks 必要的接口声明 . 这是 Delphi 声明的 ChatEvents ChatServerEvents:
    { IChatEvents }
    IChatEvents = interface
     ['{75F9A466-518A-4B09-9DC4-9272B1EEFD95}']
     procedure OnLogin(const aUserID: String);
     procedure OnLogout(const aUserID: String);
     procedure OnSendMessage(const aUserID: String;
                  const aMessage: String);
    end;
     
    { IChatServerEvents }
    IChatServerEvents = interface
     ['{E80B0A2E-96ED-4F38-A6AC-E4E0B59F27F3}']
     procedure OnSystemShutdown(const ShutdownDelay:
                  Integer; const Reason: String);
     procedure OnMandatoryClose(const ClientID: String;
                  const Reason: String);
    end;
    下面的代码是执行在 CharService 中的 Login 方法 , 他触发了所有客户端 OnLogin 事件 :
    procedure TChatService.Login(const UserID: String);
    begin
     { Checks if the user is already logged in }
     if fUsers.IndexOf(UserID)>=0
        then raise Exception.CreateFmt('User %s is already logged in',
                                      [UserID]);
     
     { Adds the user to the list of logged users }
     fUsers.Add(UserID);
     Session.Values['UserID'] := UserID;
     
     { Generates the OnLogin event }
     (EventRepository as IChatEvents_Writer).OnLogin(Session.SessionID,
                                                      UserID);
    end;
    最后一行代码 (EventRepository asIChatEvents_Writer).OnLogin(Session.SessionID, UserID); 在所有的客户端触发 OnLogin 事件 . 虽然开起来有些零乱 , 但是这样很简单而且与标准控件事件同样工作 . 这段代码与 TButton.Click 方法等效 :
    procedure TButton.Click;
    begin
     //...
     if Assigned(OnClick) then OnClick(Self);
    end;
    主要的不同是事件 1 在服务器端触发并有多个接收者 ( 广播 ), 而事件 2 不是立即执行的 , 因为实际上 OnLogin 调用存储后有其它用户触发 .
    EventRepository 属性指向一个拖放到主窗体的存储对象 , 其中存储了 OnLogin,OnSendMessage 等序列化方法和其参数 . IChatEvent_Writer 是在声明 ChatEvents 时生成的特殊接口 , 并可以在存储器中初始化 IChatEvent 消息 . 代理依赖事件存储器就像标准的 RemObjects 代理依赖传输端口一样 .
    TChatEvents_Writer.OnLogin 被包含在 ChatLibrary_Intf.pas 文件 :
    procedure TChatEvents_Writer.OnLogin(const Sender : TGUID;
                const aUserID: String);
    var __eventdata : Binary;
    begin
     __eventdata := Binary.Create;
     try
        __Message.Initialize(NIL, 'ChatLibrary',
                             EID_ChatEvents, 'OnLogin');
        __Message.Write('aUserID', TypeInfo(String), aUserID, []);
        __Message.Finalize;
     
        __Message.WriteToStream(__eventdata);
     
        Repository.StoreEventData(Sender, __eventdata);
     except
        __eventdata.Free;
     end;
    end;
    就像我们期待的一样 , 这也是自动生成的 .
    在服务器方法中 , 下面的是在客户端向其他客户端发送信息时由此客户端触发的代码 :
    procedure TChatService.SendMessage(const MessageText: String);
    var thisuserid : string;
    begin
     { Extract the name of the user invoking this method
        by reading session information }
     thisuserid := VarToStr(Session.Values['UserID']);
     
     { Generates the OnSendMessage event }
     (EventRepository as IChatEvents_Writer).OnSendMessage(
          Session.SessionID, thisuserid, MessageText);
    end;
    又一次使用了一行代码触发远程事件 .
    广播服务事件 客户端
    写客户端相应服务器事件也很简单 . 基本上只要实现事件接口 (IChatEvents IChatServerEvents) 及通知 RemObjects 框架对象已经实现了这些接口 .
    一个新的控件 TROEventReceiver 在轮询远程事件存储器 , 周期性的查看服务器是否有未处理的消息并在需要的时候调用对象方法 .
    客户端包含一个叫做 EventReceiver TROEventReceiver 控件 . 在客户端例程中 , 主窗体实现了 IChatEvents IChatServerEvents 接口 , 声明如下 :
    TClientForm = class(TForm, IChatEvents, IChatServerEvents)
    //...
    protected
     { IChatEvents }
     procedure OnSendMessage(const aSender, aMessage : string);
     procedure OnLogin(const aUserID : string);
     procedure OnLogout(const aUserID : string);
     
     { IChatServerEvents }
     procedure OnSystemShutdown(const ShutdownDelay: Integer;
                                 const Reason: String);
     procedure OnMandatoryClose(const ClientID: String;
                                 const Reason: String);
    //...
    end;
    当用户点击 Login 按钮 , 下面的代码将执行 :
    procedure TClientForm.bbLoginClick(Sender: TObject);
    begin
     try
        ROChannel.TargetURL := cbServer.Text;
     
        { Calls the remote login method }
        fChatService.Login(UserID);
     
        { Register the event handlers using the
          TROEventReceiver called EventReceiver }
        EventReceiver.RegisterEventHandlers(
          [EID_ChatEvents, EID_ChatServerEvents],
          [Self, Self]);
     
        { Starts polling }
        EventReceiver.Active := TRUE;
     
        fLoggedIn := TRUE;
     finally
        ToggleControls;
     end;
    end;
    方法 TROEventReceiver.RegisterEventHandlers 获取一系列的回调接口 ID (parameters [EID_ChatEvents, EID_ChatServerEvents]) 及实现他的对象 ( 这个例子都是 self, 因为这里都是用 MainForm 实现这两种事件处理接口的 ).
    EID_xxx 是与回调接口同名的字符串常量 , 声明如下 :
    unit ChatLibrary_Intf;
    //...
    const
    //...
     { Event ID's }
     EID_ChatEvents = 'ChatEvents';
     EID_ChatServerEvents = 'ChatServerEvents';
    IChatEvents IChatServerEvents 事件到达 ,MainForm 中相关的方法将自动执行 , 这就像 OnClick 事件一样 , 这些都是对开发者透明的 .
    下面的一小段程序展示了 OnLog,OnSendMessage,OnSystemShutdown 的实现 , 这些方法觉定了在运行期如何输出信息 :
    procedure TClientForm.OnLogin(const aUserID: string);
    begin
     WriteMessage(mtSystem, '', 'User '
                                 +aUserID
                                 +' just logged in');
    end;
     
    procedure TClientForm.OnSendMessage(const aSender,
                                        aMessage: string);
    begin
     WriteMessage(mtMessage, aSender, aMessage);
    end;
     
    procedure TClientForm.OnSystemShutdown(const ShutdownDelay: Integer;
                                           const Reason: String);
    begin
     Beep;
     MessageDlg(Format('The server will be shut down in %d minutes.'
                        +#13'Reason: %s', [ShutdownDelay, Reason]),
                 mtWarning, [mbOK], 0);
    end;
    WriteMessage 是一个向 MainForm 窗体的 Memo 控件显示文本信息的简单函数 . 紧记 , 除了调用 EventReceiver.RegisterEventHandlers 和用户注销时的 EventReceiver.UnregisterEventHandlers, 实现消息处理接口外 , 不再需要其他的处理事件了 .
    Master Server
    The RemObjects SDK 允许我们将 Session 信息存储在内存中或数据库中 , 如果你想要你的系统均衡负载和容错 , 需要将 Session 保存到每个服务器都可以存取的数据库中 , 这样客户端无论连接到哪台服务器都可以取出一致的 Session 信息 . 这个功能就是 RemObjects SDK 2.0 TRODBSessionManager 提供的 . 但是 , 数据库 Session 管理折中了速度和需求 .
    存取远程数据库比使用内存数据要慢 , 并且要设置存储 Session 信息必需的表结构 .
    RemObjects Master Server (ROMS) RemObjects SDK 3.0 标准提供 , 可集中高效的处理我们的 Session 和服务器事件数据 . 安装 Snap 后可以高效简单的对数据库表操作 .
    ROMS NT 服务或独立可执行程序的方式发布 API, 使用这些 API 我们就可以存取 Session 信息和服务器事件 . 这些 API 使用 RemObjects 二进制流消息通过 HTTP,TCP,UDP Win 消息通道传递 . 由新的控件 TROMasterServerSessionManager TROMasterServerEventRepository 封装 .
    记住 , 你可以使用这些 API, 并且有完整的 ROMS 源码 , 但是 RO3.0 提供的新控件使我们不需要直接去调用 ROMS 方法 , 事实上我们只需用 TROMasterServerSessionManager 替换 TROInMemorySessionManager 并设置一组属性就可以了 .
    ROMS 使用嵌入的 NexusDB 服务器保存数据 , 可以使数据吞吐率更好于重量级的数据库 . 使用 RemObjects 消息读取 ROMS 可以在不同的局域网中共享 Session.
    下面的截图展示了高版本的聊天范例 :
    这个高版本的聊天程序展示了两个客户端连接到分离的两个服务器上 , 可以像连接到一个服务器一样交换信息 . 这两个服务器可能是一个服务器丛的一部分 , 或在远程存放并连接到同一个 ROMS.
    ROMS 联合客户端特性可以支持均衡负载和容错处理 , 这样我们的系统可以 24X7 不间断运行 , 并可以跨多局域网段 , 提供 Session 数据共享功能 .
    ROMS 源码包含于 RemObjects SDK 3.0, 需要非附加许可证文件 .
    ServiceBuilder 3
    RemObjects SDK 3.0 的一个新特性就是提供了一个新的 ServiceBuilder 3, 它完全从写 , 提供了更多用户接口和自定义插件 . 事实上 SB3 中所有的功能都是插件式的 , 以后会增加新的功能 .
    这里是 SB3 的插件基础 , 这些可以用附加的插件修改和扩充 :
    • Library编辑器就像你在上面的截图中看到的默认编辑器 (使用gridsedit boxes 编辑库). 附加的插件可以提供不同的编辑界面.他们可以含基于UML的库视图,允许你在类图中编辑服务方法和结构体,或高亮的语法显示.
    • Library验证器- Library 验证器可以实现检查自定义的规格.默认验证器可以检查错误元素(像声明数组没有类型等),或不合法标识(使用保留字if),自定义验证器可以扩展这些功能,例如强制命名规则或其它标准.
    • Library 视图- Library编辑器一样, Library 试图可以自定义RODL Library视图符合你的特殊要求.可能是服务方法和参数类型相互依赖的图表视图,WSDL视图,或其它的视图.
    • CodeGens可能是最重要的可扩展特性, 插件式的CodeGens允许SB3为不同的语言扩展自定义的代码生成器. 这样将使RemObjects SDK在将来扩展支持其他的平台 .SB3可支持C#,VB.NET,C/C++,Java或其它语言. 你也可以为现存的任何语言加入自己修改的代码生成器,或提供修改的接口适合特殊要求.
    • Identifier Validators标识符验证插件提供在特定语言中验证标识符是否合法的功能. 例如,this这个方法名字可能在Delphi中是可以接受的,但是在C#C/C++中与预留字符串向违背.
    • Importers自定义导入接口可以让你从自定义数据中引入库,默认的,库元素可以从WSDL,Pascal,COM类型库或RODL文件中引入.通过SB3插件功能可以增加自己的导入接口.
    SB3 插件式的 SDK, 有很多建立自定义插件的信息和范例 , 将对所有的 RemObjects SDK 3 用户免费 .
    插件将在 Delphi7 Hydra 下构建 , 提供新的修订的 TRODLLibrary 结构可轻易工作和扩展加载库 .
    下面的截图展示了一系列插件在 SB3 中加载 :
    SB3 增加功能 :
    • 按可视节点分组的库元素有利于更好的组织大型库
    • 增强的文档功能可以查看所有的库文档,包括个别函数和结构体成员.
    • 支持新回调接收器Callback Sink类型和复杂的异常类型.
    下面的截图展示了运行中的 SB3, CodeGen 菜单中支持不同的语言和两个三方插件编辑库 ,
    结论
    RemObjects SDK 3.0 建立在 2.0 版本 , 增加了很多新的强大功能 :
    • 服务器端测试和图形功能
    • 改进的Service Builder可以通过Hydra插件扩展
    • 广播服务器事件模拟无状态,可预定的回调
    • 支持COM Active 脚本
    • 强大的Master Server保证高级可预定性
    就像我们说的 : 远程 , 灵活的方式 .
     
     
    展开全文
  • RO45 – 如何写RemObjects SDK 服务 (.NET Version)本文说明如何创建你的第个RemObjects SDK 服务. 在下相关文档中 (RO46)中说明如何基于这个服务端创建客户端. 选择服务类型第步是选择你要创建的服务类型.在...
  • 定义区分很明确但不够直观,看下图,Ro是由运放内部输出决定的,不随闭环增益的变化而变化,可以理解为运放的本征参数。 而Rout则不同,它是指运放构成闭环放大电路后从输出端看进去的阻抗,需要在输出端进行测量...
  • RO05 – 如何创建RemObjects SDK 服务(Delphi Version)本文档向你展示如何使用RemObjects(Delphi版)创建第个服务.读了本文档后你可以继续读相关文档:
  • 获取URL中的一级域名

    千次阅读 2015-10-16 11:29:12
    对网络数据的处理中,常常用到对url进行分类,在内存中建立字典,以一级域名作为键,是很好的分类方式;苦于对于一级域名的提取,这里写了个小工具,要是还有更好的方法,请大家分享
  • 输入源是个电压源那么Ri越大越好,因为Ri越大分的输入的电压就越大,放大的就越好 对于Ro来说, 如果想要输出稳定的电压,那么Ro越小越好。类比电压源 如果想要输出稳定的电流,那么Ro越大越好,类比电流源 如下图...
  • 本文的标题有此让人迷惑,运放的输出...看下面的图,Ro是由运放内部输出决定的,不随闭环增益的变化而变化。可以理解为运放的本征参数。 而Rout则不同,它是运放构成环闭放大电路后,从输出端看进去的阻抗,需...
  • RO05 – 如何创建RemObjects SDK 服务(Delphi Version) 本文档向你展示如何使用RemObjects(Delphi版)创建第个服务.读了本文档后你可以继续读相关文档:  
  • 在写“保持容性负载稳定的六种方法”部分时发生了件有趣的事情。我们选择了具有“轨至轨”输出的CMOS运算放大器并测量了ROUT,但在高频区域没有环路增益,因而无法确定RO。根据RO测量结果,我们预测了在1μF容性...
  • 我们关心的另个关键曲线是RO变成最大值时的轻负载。我们并不十分清楚该工作点的位置,原因是我们不能看到OPA348 A-B类偏置的内部,但在计算AC传输曲线之前,我们需要知道该点的位置。使用图7.34中的技术和电路将...
  • 从图7.16中我们可以看出,ZO由RO决定,RO对于放大器的单位增益带宽而言是常数,其会随着负载电流的上升而下降。请注意,ZO是根据源极和漏极电流在轻负载条件下以及重负载条件下源极或漏极ZO无显著差别的情况下得出的...
  • ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写...RAM有两大类,种称为静态RAM(Static RAM/SRAM),SRAM速度非常快,是目前读写最快的存储设备了,但是它也非常
  • 有关RO2模拟器与开私服的一点联想

    千次阅读 2007-10-15 01:19:00
     关于“模拟器”与“私服”的关系,在我看来,“模拟器”是个软件产品,通俗点讲是个东西。“私服”可以算作是提供的项服务。简单来说,你要提供“私服”必须先取得“模拟器”这个东西,然后把“模拟器”这个...
  • Android 开发中uboot传给Kernel ...property是Android开发中使用频率非常高的种机制,用来向上层软件暴露产品或者系统属性, 下面是在Android 系统中通过getprop命令查看到的一些property: [ro.boot.assm_mn]: [T...
  • ***resolve ro a path with no project.properties file for ***
  • 2.1.3 Kernel command line: ro root=/dev/hda1

    千次阅读 2010-06-25 14:22:00
    印一些调试信息并在启动结束时切换到runlevel的第3(初始化进程的启动信息打印后就会了解runlevel的含义);如果bootmode参数 被设置为0,意味着你希望启动过程相对简洁,并且设置runlevel为2。既然已经熟悉了...
  • VBB给了输入回路个静态工作点使发射结正偏,VCC给了输出回路个静态工作点使集电结反偏。 图b是基本共基放大电路的交流通路 图c是基本共基放大电路交流通路的简化H参数等效模型 如果Re很大的话,基本共基放大...
  • 以cortex-M3为例,例如STM32F103 这篇文章要讲2个问题: 1、编译出的程序(指令)、变量的存放位置、大小?...Program Size: Code=1148 RO-data=424 RW-data=20 ZI-data=1636 其中: ①Code为代码,本质上就...
  • 看到很多人被QTP弄得晕头转向,我深有感触,有句话突然浮上心头“不识庐山真面目,只缘身在此山中”。当你接触并研究过多个工具之后,会发现道理原来就是这么简单。这里也送迷路者句话:工具永远只是工具,工具...
  • 一级反渗透纯水设备中所使用的反渗透膜源自国外进口,能有效去除水中无机盐、重金属等有害物质,去除率达99.7%。整套设备可实现自动清洗,在线监测水质情况和设备运行状况等。反渗透系统能够截留溶液盐分以及分子量...
  • 第三类工作使用深度卷积神经网络直接提供类别像素标注,甚至可以放弃分割。论文14,52的免分割方法直接用全卷积方法将深度卷积神经网络应用到整幅图像上,将深度卷积神经网络的最后全连接层转换成卷积层。为了处理...
  • 路由套件 RoutingKit是个C ++库,提供高级路由计划功能。 它是由的开发的。 最突出的组件是基于索引的数据结构,称为(可自定义)收缩层次结构,该结构允许在几毫秒或更短的时间内对大陆大小的数据集回答最短... ro
  • 更多相关u-boot博客 /*U-boot启动信息*/ DataFlash:AT45DB321 Nb pages: 8192 Page Size: 528 Size= 4325376 bytes ...Logical address: 0xC...Area 0: C0000000 to C0003FFF (RO) Area 1: C0004000 to C0007FFF
  • 写在前面 最近在啃拉扎维的《模拟CMOS集成电路设计》。一会看得懂一会看不懂,看懂了觉得拉扎维真太牛逼了,看不懂就觉得自己是...这是个单位增益缓冲器,实质就是把单端输出的基本结构(a)的输入输出相连,其实我
  • 篇博文讲述了如何展开个两的数据源,那么我们就接着改例城讲解一下数据的展开与收回。在这里主要是为了讲解两个知识点,在tableview中插入数据与删除数据。  首先呢,我们要思考一下,如何设置自己的算法,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,125
精华内容 8,850
关键字:

一级ro