客户端UI开发浏览器编程技术浅析一

           我们在客户端编程中,经常会遇到比较复杂的UI交互,特效等。最开始最容易上手的是内嵌浏览器控件,在2000年左右的时候,主要页面和交互都用html来实现,有过mfc开发经验的vc程序员都知道,在开发向导里头拖入一个IE控件,一个网页就可以展示出来了。其他windows平台的编程语言如dephi, c#, vb等都有类似的经验体会。要show一个网页就是如此的简单,但是那时候的html还没有现在如此之强大,开发一个网页, 尤其是漂亮的网页也不是一个简单的事情。绝大多数的内嵌浏览器都是IE控件,有着一样的滚动条,右键菜单。

          后来很多UI开发框架出来了,包括当时著名的MFC,影响了很大一批人(虽然到现在MFC几乎已经被废弃了)。MFC是基于windows原生窗体式控件的封装,每个小的组件就是一个独立的窗体,据说里面有n多设计上的缺陷,要做个漂亮的界面也不容易。不过这个时候程序员们基本有个共识,以前的IE控件式没什么技术含量,本地交互也很困难,很难做到原生程序那么如臂使指,MFC 才比较有成就感。拖控件是UI开发的第一个步骤。那时候软件数量和种类都比较少,MFC是很多vc程序员的首选,用户首先关注的是软件的功能。

          随着互联网的进一步发展,同类的软件层出不穷,随便百度一个功能型软件都能找出一大堆,用户已经不再满足功能上的实现,视觉上的享受也成为一个软件是否有吸引力的重要指标。窗口式拖控件的做法越来越显出其弊端,每个控件都是一个子窗体,消耗资源比较多,控件默认都是随windows原生风格而出现,要想定制十分之困难。大家都被绑在微软的windows上,别提跨平台了。Direct UI应运而生,浑然一体的界面风格,方便的UI资源编辑,支持换肤不再是一件很麻烦的事情,一些号称跨平台的库也出现了,如Qt,wxwidgets。原先的窗体式控件被抽象成一张画布上的一个子元素,各种控件,消息响应的概念仍然借用过来,但具体实现已经脱离了windows窗体的先天限制。静态布局加脚本语言控制渐渐成为主流。

          谈了这么多UI开发发展中经历的历程,其实我很惭愧,因为我并不擅长做UI,也没有很多的UI开发经验,这纯粹是我从底层技术发展变迁总结的一点个人愚见。但由于工作关系,又与浏览器打了不少交道,所以才产生了写这篇文章的想法,仅供有同样问题的后来者参考。

         谈到浏览器,web开发人员都能意识到它本质上其实是一个运行html+js+css的工具软件。输入是不同种类的文本,输出是视觉上各种各样的效果,并且能和用户交互。在近几年的项目中,我也总是在思考客户端最好的UI开发模式是什么,大量重复的UI控件的开发工作怎么才能最简单高效的完成,Direct UI的接口如何方能简单好用。及至用过IE做界面开发,又转用过cef框架的webkit做界面开发之后,我才意识到其实浏览器本身就是一个设计得很好的Direct UI开发框架。静态布局有html文本去描述,动态交互有js文本去执行。完全符合了静态布局+动态控制的需求!没有东西是万能的,使用浏览器框架开发好处不用多说了,只要会html和js的web开发者就能做出很漂亮的界面,尤其是html标准日益规范化,强大化,html5的出现更是让前端开发者可以方便的用实现一个web版的本地应用程序。我在这里主要谈一下它的缺点,与其他UI引擎库相比,浏览器本身是个很重的开发框架,它包括了太多的东西,http网络请求,本地cache和cookie的存储,js脚本引擎解释,UI渲染。它的UI渲染引擎十分庞大丰富,全是html组件,有不少内置的特性,而且全部脚本化了。一个UI引擎最关注的的是界面渲染,能不能实现基本特效,是否能方便的扩展。但是浏览器显然不止这些,它从设计之初就更关注web页面的下载和渲染,它的渲染引擎很难扩展(也许更专业的人士觉得它简单),像是一个黑盒子,完全从html标准而来!幸而现在html标准发展很迅速,前些年的时候就只能做很粗糙的界面或者要花很大功夫。浏览器还要支持多窗口文档浏览,并发访问,所以它通常有很复杂的线程进程模型,而UI引擎本身是个库,可能根本没有线程模型,由调用者自己随心设计,这就使得浏览器要深入掌握更加困难,总会有很多东西无法掌控的感觉,不过这不影响它的使用,因为其实嵌入一个浏览器并和它做一些基本交互还是比较简单的。最后还有一个对某些应用来说或许很致命的缺点,太庞大的系统框架导致打包浏览器的运行时库非常之大,一般都超过20M,如果你的程序本身逻辑处理只有不到1M,只有一两个文件,但为了做UI渲染就不得不加上浏览器的所有运行库,看着发行包里面自己的代码只占10%都不到,开发者情何以堪?如果不带,只有微软的IE控件基本所有用户电脑上都有,但是那就意味着你的网页要做无数的浏览器兼容工作,这对IE来说无疑是个噩梦!

       总结一下,浏览器框架更倾向于一个适合web页面展示的平台级应用,如果你本来就是这样的应用,那这无疑是很好的选择;如果本地特性更多,交互逻辑更复杂,那么浏览器可能不是一个好的选择,它对前期开发原型十分方便迅速,但是越到后期越有定制需求的时候就需要更加深入的研究它了。接下来的几篇文章会依次详细的总结一下IE控件和cef框架的开发中用到的一些技术点。按照浏览器通常会提供的接口,浏览器的一个基本模型如下:

       


             IE和cef封装的浏览器框架模型其实和上图都是差不多的,只不过具体的接口,细节不同。我个人认为对浏览器的理解研究还比较浅薄,但使用这些接口已经能满足大部分应用程序的需要了。总体来说,浏览器和natvie交互的两个关键技术是 1. 自定义协议的处理 2.native对象导入到js环境中.其他都是一些细节点,但有时候研究起来也很费劲。这再一次印证了前面的观点,自定义协议处理实现了静态布局加载,natvie对象交互实现了动态控制通信.这正是一个完整的UI引擎应该提供的两个基本特性。后面的文章会逐渐阐述一些关键技术点和相关示例代码。


      

      


网络编程,当然要用到Windows Socket(套接字)技术。Socket相关的操作由一系列API函数来完成,比如socket、bind、listen、connect、accept、send、sendto、recv、recvfrom等。调用这些API函数有一定的先后次序,有些函数的参数还比较复杂,对于开发者来说,不是很好用。于是,微软的MFC提供了两个类:CAsyncSocket和CSocket,极大地方便了Socket功能的使用。   CAsyncSocket类在较低层次上封装了Windows Socket API,并且通过内建一个(隐藏的)窗口,实现了适合Windows应用的异步机制(Windows Socket API默认情况下工作在阻塞模式,不方便直接在消息驱动的Windows程序上使用)。CSocket类从CAsyncSocket类派生,进一步简化了Socket功能的应用。不过很遗憾,正因为这两个类都内建了一个窗口,它们并不是线程安全的(thread-safe);如果要在多线程环境下应用Socket功能,建议自行封装Socket API函数。 基于TCP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到一个本地地址和端口号上(bind) 3、将套接字设为监听模式,准备接受客户请求(listen) 4、等待客户请求,请求到来时接受请求,建立链接,并返回 一个新的基于此次通信的套接字(accept) 5、用返回的套接字和客户端进行通信(send、recv) 6、返回,等待另一客户请求 7、关闭套接字 基于TCP的socket编程的客户端程序流程如下: 1、创建套接字 2、向服务器端发送请求(connect) 3、和服务器端进行通信(send、recv) 4、关闭套接字 基于UDP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到本地地址和端口号上(bind) 3、等待接收数据(recvfrom) 4、关闭套接字 基于UDP的socket编程的客户端程序流程如下: 1、创建套接字 2、和服务器端进行通信(sendto) 3、关闭套接字 异步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而同步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。   阻塞套接字是指执行此套接字的网络调用时,直到成功才返回,否则一直阻塞在此网络调用上,比如调用recv()函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在recv()这个函数调用上,直到读到一些数据,此函数调用才返回;而非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的。   对于这些概念,初学者的理解也许只能似是而非,我将用一个最简单的例子说明异步非阻塞Socket的基本原理和工作机制。目的是让初学者不仅对Socket异步非阻塞的概念有个非常透彻的理解,而且也给他们提供一个用Socket开发网络通信应用程序的快速入门方法。操作系统是Windows 98(或NT4.0),开发工具是Visual C++6.0。   MFC提供了一个异步类CAsyncSocket,它封装了异步、非阻塞Socket的基本功能,用它做常用的网络通信软件很方便。但它屏蔽了Socket的异步、非阻塞等概念,开发人员无需了解异步、非阻塞Socket的原理和工作机制。因此,建议初学者学习编网络通信程序时,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、非阻塞Socket编程机制的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值