从事软件开发行业十多年,专注于网络通信技术和网络语音视频技术,擅长系统架构设计、系统性能优化等。zhuweisky.cnblogs.com
当我们使用像Skype、QQ这样的工具和朋友流畅地进行语音视频聊天时,我们可曾想过其背后有哪些强大的技术在支撑?本文将对网络语音通话所使用到的技术做一些简单的介绍,算是管中窥豹吧。 一.概念模型 网络语音通话通常是双向的,就模型层面来说,这个双向是对称的。
概述 ESPlus 是基于网络通信框架ESFramework通信框架通信框架的增强库。为了更贴近实际应用,加快网络通信系统的开发,ESPlus在ESFramework通信框架原生功能的基础上,进行了再次封装,提供了大多数通信系统中经常用到的组件和功能。
距离ESPlus 2.0发布已经有半年的时间了,在这半年多的时间中,有数十家公司在他们的项目或产品中正式使用了ESFramework 4.0,并根据实际的使用状况,给我们反馈了很多有益的建议。基于这些建议和ESFramework的长期发展规划,今天,我们推出了ESPlus 3.0 。
当我们把基于.NET 2.0开发的网络客户端程序部署到windows 7 家庭普通版上启动时,报出了“配置系统未能初始化”的异常,在另外一些windows 7 家庭普通版的机器上则报出“应用程序无法启动,因为应用程序的并行配置不正确 ”的异常。
在分布式通信系统中,安全无疑是非常重要的。ESFramework通信框架提供了哪些安全保障了?由于ESFramework通信框架是应用层的开发框架,那么本文我们只讨论ESFramework通信框架在应用层涉及到的安全问题。
ESFramework开发手册系列文章已经详细介绍了如何使用ESPlus提供的ESPlus.Application.CustomizeInfo空间来发送和处理自定义信息,而且,在我们在前面介绍的demo中,也展示了如何定义信息类型、信息协议,以及如何实现ICustomizeHandler来处理接收到的信息。
我们的一个C#项目需要调用C++的dll,通过Pinvoke进行方法调用。其中的一个方法及其参数的定义是这样的: [StructLayoutAttribute (LayoutKind.
在程序之外,是程序员的生活。 当我们刚刚告别校园成为一个程序员时,大都拥有成功的梦想、万分的激情,那时的我们也拥有精力充沛的健康身体。 随时间流逝,5年过去了、10年过去了,也许,梦想可能渐渐暗淡,激情慢慢消退。
在之前版本的Rapid引擎中,是没有提供客户端登陆验证的机制的,如果要验证用户的帐号密码信息,我们只有自己手动通过自定义信息来实现。在2011.04.25发布的新版本中,客户端Rapid引擎,则内置了在初始化时验证用户的帐号密码的功能,这使得登录验证变得更加简单。
本文我们将介绍在ESFramework 4.0 快速上手(08) -- 入门Demo,一个简单的IM系统(附源码)的基础上,增加文件传送的功能。如果不了解如何使用ESFramework提供的文件传送功能,可以先看看ESFramework 4.0 快速上手(13) -- 文件传送,如此简单一文的详细介绍。
在所有的通信系统中,文件传送是最常见也是最重要的功能之一,ESFramework对文件传送的强大支持也是其亮点之一,使用ESFramework可以非常轻松地实现与文件传送相关的所有需求。ESPlus.Application.FileTransfering命名空间完整地解决了通信中与文件收发相关的问题,可以支持客户端与客户端之间的文件对传、上传文件到服务器以及从服务器下载文件,并且可以监控每个文件传送的实时状态、且内置了文件续传等功能。
(本文所介绍的新功能位于2011.04.18发布的最新版本中,此次版本变更请参见ESFramework通信框架通信框架 4.0 版本升级说明(持续更新)) 使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了,那么,如何得知接收方是否已经收到了我们发出的信息了呢?特别是针对一些非常重要的信息,确认对方已经收到是非常重要的。
ESFramework 4.0 内核(ESFramework.dll)已经相当成熟,不会轻易修改,而在不断增强中的是ESPlus和ESFramework.SL,所以,如下的一些版本变更几乎都是针对ESPlus和ESFramework.SL的。
在ESFramework 4.0 进阶(02)-- 核心:消息处理的骨架流程一文中,我们介绍了通过挂接IMessageSpy到骨架流程,我们就可以监控到所有收发的消息。由于Rapid引擎已经为我们组装好了默认的骨架流程,如果使用Rapid引擎,我们就无法插入自定义的IMessageSpy。
在ESFramework 4.0 快速上手 -- 入门Demo,一个简单的IM系统(附源码)一文中,我们介绍了使用ESFramework的Rapid引擎开发的winform聊天程序,本文我们将在之前demo的基础上添加使用ESFramework.SL开发的Silverlight客户端。
在编码的时候,我们经常预订某个事件来处理它,但很少取消事件的预订,这种做法可能导致程序在运行时出现一些异常。 如果你的某个用于处理事件的对象不是在运行期内永久存在的(比如,不是Singleton对象),那么请记住一条规则:在该对象(事件预订者)的生命周期中只要预订了其他对象(事件发布者)的事件,那么在该对象释放时,一定要取消这些事件的预订。
前面的文章已经介绍完了基于ESFramework/ESPlus进行二次开发的所有要点,现在,我们可以开始小试牛刀了。 本文将介绍使用ESFramework的Rapid引擎开发的两个最简单的Demo,ESFramework.Demos.Simplest 和 ESFramework.Demos.Silverlight。
作为.NET平台上的通信框架,ESFramework有哪些优点了?我们有什么理由要使用ESFramework来开发自己的通信应用? 1.高性能 ESFramework底层使用IOCP模型,使得数据收发与处理达到最高性能。
在ESFramework 4.0 进阶(02)-- 核心:消息处理的骨架流程一文中我们介绍的ESFramework提供的消息处理的骨架流程,假设我们有这样的需求,我们需要在网关级消息监控器处放置两个监控器,一个用于对收到的消息进行特殊的验证,另一个用于检查重复的消息。
在ESFramework框架中基于TCP的服务端引擎(当然也包括Rapid引擎)都采用了这样一条规则:默认情况下,客户端与服务器成功建立TCP连接以后,服务端会从客户端发过来的第一条消息中取出消息头的UserID属性的值,并将其与对应的TCP连接绑定起来。
在Internet上采用TCP进行通信的系统,都会遇到一个令人头疼的问题,就是“掉线”。而“TCP掉线”这个问题远比我们通常所能想象的要复杂的多 -- 网络拓扑纷繁复杂、而从始节点A到终节点B之间可能要经过N多的交换机、路由器、防火墙等等硬件设备,每个硬件设备的相关设定也不统一,再加上网络中可能出现的拥塞、延迟等,使得我们在编程时,处理掉线也非常棘手。
《ESFramework 4.0 快速上手》系列介绍的都是如何使用Rapid引擎(快速引擎) -- RapidServerEngine 和 RapidPassiveEngine。其实,大家可以将这两个引擎看作是两个壳,内部包装的才是真正的ESFramework的网络引擎, ESFramework支持很多种网络引擎(客户端/服务端、二进制协议/文本协议、TCP/UDP),而RapidServerEngine和RapidPassiveEngine采用的是基于TCP和二进制协议的服务端引擎和客户端引擎。
Silverlight已经到4.0版本了,已经相当成熟了,在Silverlight中使用socket与服务器进行通信也是常见的需求,所以,作为.NET平台的通信框架,ESFramework支持Silverlight开发是必须的。
在ESFramework 4.0 快速上手一文中,我们讲述了如何使用Rapid引擎可以快速地上手ESFramework开发,文中介绍了使用ESPlus.Application.CustomizeInfo命名空间下的类可以发送和处理自定义消息,本文我们就通过一个简单的例子来深入讲解如何使用自定义消息。
ESFramework框架(包括ESPlus、ESPlatform)实现时就内置了相对完整的日志功能,几乎所有的异常(Exception)和错误信息都会被记录到日志。通过查看日志记录,我们可以了解到程序在运行的过程中出现了哪些非正常的状况,并且,详细的日志记录可以帮我们迅速定位问题,并解决问题。
在ESFramework 4.0 快速上手一文中,主要介绍了如何使用ESPlus.Rapid命名空间中的引擎来快速地构建基于TCP的网络通信系统,即使是使用ESPlus.Rapid来进行ESFramework快速开发,也还有很多可以介绍的内容,于是,我想再多写几篇文章来说明现实通信系统中的一些常见需求如何使用ESFramework快速实现。
以前写的关于架构经验方面的文章(如上一篇实战中演化的三层架构)都是从整体的角度出发的,采用全局的视角,本文我们将拉近镜头,聚焦于日志记录这一块。随着做软件的时间越长、经验积累得越来越多,就越觉得日志记录的重要。
Win7与原来的XP和Win2003相比,安全控制方面更严格。比如,当我们以administrator登陆XP或Win2003时,运行所有的程序即是以管理员的身份启动的。但当以administrator登陆Win7时,通常状态下,运行普通程序是以普通用户的身份启动的。
本文所描述的TCP代理服务器工作于网络协议层次中的应用层,位于传输层之上。只要是以TCP的方式为客户提供服务的(包括我们的HTTP服务器,HTTP底层走的仍然是TCP),我们都可以在真正的TCP服务器前面增加代理服务器。
我们的网络游戏采用tcp进行通信,服务端程序绑定8300端口,为游戏客户端提供服务,游戏已经上线稳定运行两年多,从今年9月份开始至今碰到了3次攻击,3次攻击所导致的情况一样,描述如下: (1)从应用层上来看,攻击者每次攻击时,与8300端口都有建立最多两、三百个tcp连接。
(题外话:前面连续N篇介绍都是一些应用比较复杂的类,这篇来个简单易懂的) 1.缘起: .NET Framework提供的Soap序列化的方式可以实现对象的xml序列化和反序列化(object xml) ,但是它有三个缺点: (1) 它要求对象的类型定义时必须打上[Serializable]标签,这是强侵入性的。
1.缘起: 在增量自动获取器章节的缘起部分,我们曾提到增量缓存,本节我们将深入探讨它以及用于管理增量缓存的管理器。我们还是以增量自动获取器章节提到的例子作为基础,并做更进一步的讨论。 OK,现在让我们开始这有趣的旅程。
1.缘起: 假设我们的订单报表系统,需要能够实时地统计当天的已成交订单的报表。最直观的解决方案就是,当每次接收到查询报表的请求时,就从存储设备读取当天所有已成交的订单,然后再进行分析计算给出结果。
Speex是一套开源的音频编解码库,最新版本还包含了回音消除和防抖动等功能,如果我们想开发语音聊天或视频会议这样的系统,Speex将是一个不错的选择。到 http://www.speex.org可以下载Speex的源码(编译后的dll为libspeex.dll),最新版本为1.2。
本实验用于测试ESFramework网络通信框架服务端引擎的性能,测试程序使用ESFramework 4.0版本。 一.准备工作 测试的机器总共有3台,都是普通的PC,一台作为服务器,两台作为客户端。
(在阅读该文之前,请先阅读 ESFramework 4.0 概述 ,会对本文的理解更有帮助。) ESFramework/ESPlatform 4.0 的终极目标是为百万级的用户同时在线提供支持,因为强大,所以使用也较为复杂,配置也较多。
windows 7和vista提高的系统的安全性,同时需要明确指定“以管理员身份运行”才可赋予被运行软件比较高级的权限,比如访问注册表等。否则,当以普通身份运行的程序需要访问较高级的系统资源时,将会抛出异常。
ESFramework网络通信框架 是一套性能卓越、稳定可靠、强大易用的跨平台通信框架。也是.net平台首屈一指的成熟的C#网络通信框架。从最初的单纯的C#网络通信框架,历经10年,已经发展为支持包括安卓、IOS、Xamarin等多个平台的跨平台通信框架。
当Form包含自定义控件,或UserControl存在嵌套时,外层的对象就会接收不到KeyDown等事件了,但是,我们可以通过override基类的ProcessDialogKey方法来达到同样的效果,比如: protected override bool Proce...
1.缘起: 从IMultiTree到IAgileMultiTree,一切进展得都不错。但是,还有改进的地方。多叉树的一个优点在于,根据指定的节点能够非常迅速地找到其所有的子节点。但是缺点在于,根据节点值的ID定位到目标节点不够快,因为需要对所有的节点进行遍历操作。
如果我使用TcpListener绑定本地的7000端口,并启动监听。然后,再使用TcpClient绑定本地7000端口,此时需要开启TcpClient的地址重用设置: TcpClient.
1.缘起: 我们还是以多叉树IMultiTree章节介绍的那个例子来继续讲解。假设,在系统运行的过程中,集团又成立了分公司D及其下属的一些单位,这些资料已经被存入了数据库中,但是这些信息在我们当前正在运行的MultiTree实例中并不存在,如果此时向MultiTree实例请求与D分公司相关的信息,那么将一无所获。
对于集合的遍历,使用foreach是非常方便的,但是Emit动态生成foreach的代码就要复杂很多。它涉及到以下几个方面: (1)IEnumerable 是所有可枚举类型的基础接口。 (2)IEnumerator,通过IEnumerable 接口的GetEnumerator方法可以获取枚举器IEnumerator,而对集合元素的遍历正是由IEnumerator的MoveNext方法完成的。
我们在使用GDI+实现类似画图板这样的系统时,经常需要支持平移、滚动条、缩放等功能、解决绘制时的闪烁,对于缺乏GDI+开发经验的朋友,经常会在这些问题上纠缠一段或长或短的时间。在这里,我将自己的经验小结一下,给后来的朋友作个参考。
1.缘起: 当数据源中的数据量多到一定程度时,我们在查询时就经常使用分页策略。如果数据源是一个完整的整体,这没有什么大不了的,我们经常就在做类似的事情。但是,如果数据源不是一个完整的整体,而是由很多有序的片段构成的,并且不同的片段可能位于不同的位置(比如,位于不同的服务器节点上的内存中),甚至,每个片段内的数据还会随着时间的变化而变化的。
1.缘起: 假设我们的会员管理系统有一个排行榜的功能,需要每隔一段时间就对系统中的所有会员(假设会员数有100万)的积分进行排序,然后对其中的前100名进行某些奖励。 这是一个典型的TopN算法――对巨大数量的对象进行排序,然后只需要取出最Top的前N名(N比对象总数小很多),作为排行榜的数据。
1.缘起: 假设我们有一个订单系统,现在这个系统要增加一个功能――允许客人查核他认为有问题的订单的详细信息。当客人觉得自己的某个订单不对劲时,他首先会从订单系统查询这个订单的详细信息,然后打电话告诉我们的客服有问题的订单的编号,客服再去查核,如果属实,客服还要进一步上报,如果该订单非常重要,则可能需要更进一步上报复查等。
1.缘起: 假设我们有一个会员管理系统,需要向各方提供查询会员基础资料的功能。会员一经注册,其基础资料就将不再发生变化(如会员帐号、身份证ID、注册时间等等)。 基于这样的需求,我们可以将会员的基础资料“永久地”缓存在内存中,从而提升对任何一个会员基础资料的查询速度。
1.缘起: ESBasic中许多管理对象的容器都用到了这个ESBasic.ObjectManagement.IObjectRetriever接口,所以单独将其提出来介绍一下。 当我们向对象容器(Container)请求某个对象时,也许目标对象还未加载到容器中,这可能是因为容器在初始化的时候就没有加载这个对象,也有可能是因为这个对象是容器初始化以后新增到数据库(当然也有可能是其它的持久化存储)的。
1.缘起: 为了提升系统的性能或减轻数据库的压力等原因,我们经常在系统中使用缓存来把那些经常使用的数据保留在内存中。如果因为某些原因,缓存中这些经常使用的数据不能及时与数据源进行同步更新,那么采用定时刷新缓存中的数据有可能就是一种合适的选择。