澳门美高梅手机网站Zookeeper那些事

一、 什么是Zookeeper

Zookeeper 是 Google 的 Chubby一个开源的贯彻,是 Hadoop 的分布式协调服务

它含一个简约的原语集,分布式应用程序可以因它实现同台服务,配置维护和命名服务等

 

澳门美高梅手机网站 1

 

话说有了WebBrowser类,终于不用自己手动封装SHDocVw的AxWebBrowser这个ActiveX控件了。这个近乎设只有看做一个暨IE一模一样浏览器,那即便绝

其次、  为什么采取Zookeeper?

绝大多数分布式应用得一个主控、协调器或控制器来治本物理分布的子进程(如资源、任务分配等)

当下,大部分运得出私有的和谐程序,缺乏一个通用的编制

和谐程序的数编写浪费,且难以形成通用、伸缩性好之协调器

ZooKeeper:提供通用的分布式锁服务,用以协调分布式应用

干燥了(还无苟直接用IE呢)。那么,无论我们是想念做一个“定制版IE”,还是想采取HTML来举行用户界面(指WinApp而非WebApp。许多单机软件

老三、  Zookeeper能拉我们举行什么?

Hadoop2.0,使用Zookeeper的事件处理确保整个集群只生一个活跃的NameNode,存储配置信息等.

HBase,使用Zookeeper的事件处理确保整个集群只发生一个HMaster,察觉HRegionServer联机和宕机,存储访问控制列表等.

,包括Windows的帮支持中心,都是HTML做的),都少不了Windows
Form和带有在WebBrowser中之Web页面的相。本文将经几独实在的例证,初

四、Zookeeper的特性

Zookeeper是简约的

Zookeeper是具备表现力的

Zookeeper具有高可用性

Zookeeper采用松耦合交互方式

Zookeeper是一个资源库

步介绍一下WinForm和WebBrowser所包含的Web页面之间的相。

五、Zookeeper的装置和布置(单机模式)

下面的代码假设你都建立了一个Windows
Form,上面有一个WebBrowser名为“webBrowser”。

1、下载ZooKeeper:

http://labs.renren.com/apache-mirror/zookeeper/zookeeper-3.4.3/zookeeper-3.4.3.tar.gz

解压:tar xzf zookeeper-3.4.3.tar.gz/2

Study
Case 1:用WinForm的Event Handler响应Web页面的轩然大波

2、在conf目录下创办一个配备文件zoo.cfg

  1. tickTime=2000  
  2. dataDir=/Users/zdandljb/zookeeper/data  
  3. dataLogDir=/Users/zdandljb/zookeeper/dataLog          
  4.   
  5. clientPort=2181  

现发出如此一个Windows
Application,它的界面及只是出一个WebBrowser,显示一个地面的HTML文件作为界面。现在的题材是,所有逻辑都好置身

3、启动ZooKeeper的Server

sh bin/zkServer.sh start, 如果想只要关,输入:zkServer.sh stop

HTML文件里,唯独“关闭”按钮遇到了困难——通常,Web页面是没有法直接决定浏览器的,更毫不说得了这WinForm程序了。

六、Zookeeper的装及部署(集群模式)

但是,在.Net
2.0中间,“由Windows Form响应Web页面的风波”已经改为了具体。

1、创建myid文件:

server1机器的始末也:1

server2机器的内容吗:2

server3机器的情节呢:3

以.Net
2.0遭遇,整个HTML文档以及那富含的逐一HTML元素,都同一个个HtmlDocument、HtmlElement之类的.Net对象对应。因此如果找到这个“关闭”

2、在conf目录下创造一个布置文件zoo.cfg

  1. tickTime=2000  
  2. dataDir=/Users/zdandljb/zookeeper/data  
  3. dataLogDir=/Users/zdandljb/zookeeper/dataLog          
  4.   
  5. clientPort=2181                                  
  6.   
  7. initLimit=5                                       
  8.   
  9. syncLimit=2                                                 
  10.   
  11. server.1=server1:2888:3888                                      
  12.   
  13. server.2=server2:2888:3888                                     
  14.   
  15. server.3=server3:2888:3888  

按钮对应之HtmlElement对象,为那个click事件添加Event
Handler即可。

七、Zookeeper的装置以及安排(伪集群模式)

1、建了3只文本夹,server1 server2
server3,然后每个文件夹里面解压一个zookeeper的下载包

2、进入data目录,创建一个myid的文本,里面写副一个数字,server1,就写一个1,server2对诺myid文件就形容副2,server3对许myid文件就描写个3

3、在conf目录下创造一个安排文件zoo.cfg

 

  1. tickTime=2000  
  2.        dataDir=/Users/zdandljb/zookeeper/data  
  3.        dataLogDir=xxx/zookeeper/server1/           
  4.   
  5. clientPort=2181                                             
  6.   
  7. initLimit=5                                       
  8.   
  9. syncLimit=2                                                
  10.   
  11. server.1=server1:2888:3888                              
  12.   
  13. server.2=server2:2888:3888                                    
  14.   
  15. server.3=server3:2888:3888  

若果HTML源代码如下:

八、Zookeeper的数据模型

层次化的目录结构,命名符合健康文件系统规范

每个节点在zookeeper中叫做znode,并且其来一个唯一的不二法门标识

节点Znode可以蕴涵数据以及子节点,但是EPHEMERAL类型的节点不可知生出子节点

Znode中的数目好生多独版,比如有一个路下存来多单数据版本,那么查询者路下之多少就是得带齐本

客户端应用可以以节点上设置监视器

节点不支持有读写,而是一次性完整读写

<html>
<body>
<input type=”button” id=”btnClose” value=”关闭” />
</body>
</html>
那找来拖欠按钮并为底补充加Event Handler的代码如下:

九、Zookeeper的节点

Znode有些许种类型,短暂之(ephemeral)和持久的(persistent)

Znode的色在开立时规定以之后非可知还修改

短暂znode的客户端会说话了时,zookeeper会将拖欠短暂znode删除,短暂znode不得以有子节点

持久znode不依赖于客户端会话,只有当客户端明确要去该持久znode时才见面让删

Znode有四栽样式的目录节点,PERSISTENT、PERSISTENT_SEQUENTIAL、EPHEMERAL、EPHEMERAL_SEQUENTIAL

 

十、Zookeeper的角色

领导者(leader),负责进行投票的倡议与决议,更新系统状态

学习者(learner),包括跟随者(follower)和观察者(observer),follower用于受客户端请求并为客户端返回结果,在选主过程中参与投票Observer可以领客户端连接,将写请求转发给leader,但observer不到位投票过程,只同步leader的状态,observer的目的是以扩大系统,提高读取速度

客户端(client),请求发起方

HtmlDocument
htmlDoc = webBrowser.Document;
HtmlElement btnElement = htmlDoc.All[“btnClose”];
if (btnElement != null)
{
     btnElement.click += new
HtmlElementEventHandler(HtmlBtnClose_Click);
}

十一、Zookeeper的各个号

始建znode时设置顺序标识,znode名称后会见增大一个价值

顺序号是一个平淡递增的计数器,由父节点维护

每当分布式系统中,顺序号可以为用来为富有的波开展全局排序,这样客户端好经逐条号推断事件之依次

其中HtmlBtnClose_Click是本下Web按钮时底Event
Handler。

十二、Zookeeper的读写机制

Zookeeper是一个是因为多个server组成的集群

一个leader,多个follower

每个server保存一卖数据副本

大局数据一致

分布式读写

创新请求转发,由leader实施

特别简短吧?那么小粗高级一点底——我们且懂一个HTML元素可能来广大饶有的轩然大波,而HtmlElement这个近乎就吃起无限常用、共通的几只。那么,

十三、Zookeeper的保证

创新请求顺序进行,来自同一个client的更新请求按照该发送顺序依次执行

数更新原子性,一涂鸦数据更新要么成功,要么失败

全局唯一数据视图,client无论连接至哪个server,数据视图都是相同的

实时性,在自然事件限制外,client能念到最新数据

何以响应其他事件也?这为很简短,只需要调用HtmlElement的AttachEventHandler就足以了:

十四、Zookeeper的API接口

  1. String create(String path, byte[] data,List<ACL> acl, CreateMode createMode)  
  2.   
  3. Stat exists(String path, boolean watch)  
  4.   
  5. void delete(String path, int version)  
  6.   
  7. List<String> getChildren(String path, boolean watch)  
  8.   
  9. List<String> getChildren(String path, boolean watch)  
  10.   
  11. Stat setData(String path, byte[] data, int version)  
  12.   
  13. byte[] getData(String path, boolean watch, Stat stat)  
  14.   
  15. void addAuthInfo(String scheme, byte[] auth)  
  16.   
  17. Stat setACL(String path, List<ACL> acl,int version)  
  18.   
  19. List<ACL> getACL(String path, Stat stat)   

btnElement.AttachEventHandler(“onclick”,
new EventHandler(HtmlBtnClose_Click));
//这无异词等价于上面的btnElement.click += new
HtmlElementEventHandler(HtmlBtnClose_Click);
对此任何事件,把”onclick”换成该事件之名即足以了。例如:

十五、观察(watcher)

Watcher 以 ZooKeeper 是一个骨干功能,Watcher
可以监督目录节点的多寡变动以及子目录的成形,一旦这些状态发生变化,服务器即会打招呼所有安装在是目录节点上之
Watcher,从而每个客户端都飞快掌握它们所关注之目节点的状态发生变化,而做出相应的影响

足装观察的操作:exists,getChildren,getData

可以触发观察的操作:create,delete,setData

formElement.AttachEventHandler(“onsubmit”,
new EventHandler(HtmlForm_Submit));

十六勾操作与zookeeper内部事件的呼应关系

 

 澳门美高梅手机网站 2

Study
Case 2:表单(form)的机关填写跟提交

十七、zookeeper内部事件与watcher的应和关系

 

 澳门美高梅手机网站 3

比方而我们的WebBrowser具有活动填表、甚至电动提交的效应,并无紧。

十八、 写操作及watcher的应和关系

 

 澳门美高梅手机网站 4

苟来一个极致简便的登录页面,输入用户名密码,点“登录”按钮即可登录。已知晓用户称输入框的id(或Name,下同)是username,密码输入框的id

十九、ACL

每个znode被创造时犹见面蕴藏一个ACL列表,用于决定谁可以针对她实施何种操作

澳门美高梅手机网站 5

 

身份验证模式有三栽:

digest:用户名,密码

host:通过客户端的主机名来辨别客户端

ip: 通过客户端的ip来分辨客户端

new ACL(Perms.READ,newId(“host”,”example.com”));

                  
这个ACL对应之身份验证模式是host,符合该模式的身份是example.com,权限的三结合是:READ

举凡password,“登录”按钮的id是submitbutton,那么我们才待以webBrowser的DocumentCompleted事件受到利用下的代码即可:

二十、Znode的节点状态

澳门美高梅手机网站 6

 

每个ACL都是身份验证模式、符合该模式之一个位置与同样组权限的整合

HtmlElement
btnSubmit = webBrowser.Document.All[“submitbutton”];
HtmlElement tbUserid = webBrowser.Document.All[“username”];
HtmlElement tbPasswd = webBrowser.Document.All[“password”];

二十一、 Zookeeper工作原理

Zookeeper的为主是原子广播,这个机制确保了逐条server之间的一块。实现者机制的商议叫做Zab协议。Zab商谈来个别栽模式,它们分别是恢复模式和播发模式。当服务启动或当首长崩溃后,Zab就进来了恢复模式,当领导被选举出来,且大部分server的形成了与leader的状态并以后,恢复模式就得了了。状态并保证了leader和server具有相同的系统状态。

一旦leader已经和大部分底follower进行了状态并后,他就好开广播消息了,即入广播状态。这时候当一个server加入zookeeper服务受到,它会于恢复模式下启动,发现leader,并与leader进行状态并。待至一块结束,它为涉足信息广播。Zookeeper服务一直保持在Broadcast状态,直到leader崩溃了或leader失去了绝大多数底followers支持。

广播模式需要保证proposal被以梯次处理,因此zk采用了递增的事情id号(zxid)来确保。所有的提议(proposal)都于给提出的当儿长了zxid。实现中zxid是一个64吗底数字,它高32个是epoch用来标识leader关系是否改变,每次一个leader被选择出来,它还见面发出一个新的epoch。低32号是个递增计数。

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重选举出一个初的leader,让所有的server都恢复至一个不易的状态。

if
(tbUserid == null || tbPasswd == null || btnSubmit == null)
    return;

二十二、Leader选举

率先看一下选的过程,zk的贯彻中之所以了依据paxos算法(主要是fastpaxos)的实现。具体如下;此外恢复模式下,如果是更刚起崩溃状态恢复的或者刚起步的之server还会从磁盘快照中平复数据和对话信息。(zk会见记录事务日志并限期开展快照,方便于回复时开展状态恢复)

每个Server启动以后还打听其他的Server它如果投票于哪个。

于另外server的打听,server每次因自己的状态都恢复自己推荐的leader的id和直达等同差处理事务的zxid(系统启动时每个server都见面推荐自己)

吸纳所有Server回复以后,就计出zxid最酷之哪个Server,并拿之Server相关信息设置成下一致赖而投票的Server。

计量这过程遭到收获票数最多之的sever为获胜者,如果获胜者的票数超过一半,则改server被增选呢leader。否则,继续是历程,直到leader被选举出来。

leader就见面初步等候server连接

Follower连接leader,将最可怜的zxid发送给leader

Leader根据follower的zxid确定同步点

成功并后通报follower 已经改为uptodate状态

Follower收到uptodate消息继,又足以又接受client的恳求进行劳动了

澳门美高梅手机网站 7

 

Observing:
观察状态,这时候observer会观察leader是否发反,然后同步leader的状态;Following: 
跟随状态,接收leader的proposal ,进行投票。并跟leader进行状态并

 澳门美高梅手机网站 8

 

Looking:
寻找状态,这个状态不晓得哪个是leader,会发起leader选举;Leading:   
领导状态,对Follower的投票进行决议,将状态与follower进行协同

tbUserid.SetAttribute(“value”,
“smalldust”);
tbPasswd.SetAttribute(“value”, “12345678”);

二十三、Zookeeper示例代码

澳门美高梅手机网站 9

 澳门美高梅手机网站 10

输出的结果如下:

早已触发了 None 事件!

testRootData   [testChildPathOne]

目录节点状态:[5,5,1281804532336,1281804532336,0,1,0,0,12,1,6]

已点了NodeChildrenChanged 事件!

testChildDataTwo

曾接触了NodeDeleted 事件!

就触发了NodeDeleted 事件!

btnSubmit.InvokeMember(“click”);
此间我们所以SetAttribute来设置文本框的“value”属性,用InvokeMember来调用了按钮的“click”方法。因为不同的Html元素,其所有的性质和方

二十四、应用场景

模仿也不尽相同,所以.Net
2.0提供了联合的HtmlElement来概括各种Html元素的以,提供了当下简单独主意为调用元素特有的效力。关于各种Html元素的

运用场景1: 统一命名服务


分布式应用中,通常用发出相同模仿完整的命名规则,既能有唯一的名号又有利于人识别和难忘,通常状态下用树形的称号结构是一个绝妙的挑选,树形的称谓结构是一个发出层次的目录结构,既对人团结而无见面还。

n  Name Service 是 Zookeeper 内置的功效,只要调用 Zookeeper 的 API
就可知促成

特性和方一览,可以查看MSDN的DHTML
Reference。

运场景2: 配置管理

n  配置的田间管理于分布式应用环境遭受酷普遍,例如同一个施用体系要差不多台
PCServer
运行,但是它运行的使用系统的一点配置起是同的,如果一旦修改这些同之配置起,那么就必同时修改每台运行此以体系的
PC Server,这样很累而爱错。

n  将安排信息保存于 Zookeeper
的某个目录节点受到,然后将持有需要改的动机器监控配置信息的状态,一旦配置信息发生变化,每台使用机器就会见吸纳
Zookeeper 的打招呼,然后从 Zookeeper 获取新的布置信息应用至网受。

Zookeeper很爱实现这种集中式的布局管理,比如用APP1的持有配置配置到/APP1
znode下,APP1所有机器一样开行就对/APP1这个节点开展督查(zk.exist(“/APP1″,true)),并且实现回调方法
Watcher,那么以zookeeper上/APP1
znode节点下多少发生变化的时段,每个机器还见面收通知,Watcher方法将会晤受执行,那么用还取得下多少即可
(zk.getData(“/APP1″,false,null));

 澳门美高梅手机网站 11

 

※关于表单的交,的确还有其他一样栽方法就是是取form元素而无是button,并为此form元素的submit方法:

动场景3: 集群管理

n  Zookeeper 能够挺容易的实现集群管理的效果,如产生差不多令 Server
组成一个劳动集群,那么必须要一个“总管”知道当前凑众多中各个台机器的劳务状态,一旦出机械不能够提供服务,集众多被另外集群必须懂得,从而做出调整重新分配服务政策。同样当多集群的服务力量时,就会多一华抑多华
Server,同样为得被“总管”知道。

n  Zookeeper
不仅会保护当前的汇聚众多被机器的服务状态,而且会选出一个“总管”,让这个总管来管理集群,这就是是
Zookeeper 的外一个成效 Leader Election。

用集群中,我们经常需要给各级一个机知道集众多被(或借助之其它有一个集群)哪些机器是生活在的,并且于集群机器因为宕机,网络断链等因能够不在人工参与的情况下迅速通报及各个一个机。Zookeeper同样很爱实现这意义,比如我以zookeeper服务器端有一个znode叫/APP1SERVERS,那么聚集众多被各个一个机开动
的时段都失去之节点下创造一个EPHEMERAL类型的节点,比如server1创建/APP1SERVERS/SERVER1(可以采用ip,保证不重复
复),server2创建/APP1SERVERS/SERVER2,然后SERVER1和SERVER2都watch
/APP1SERVERS这个父节点,那么为不怕是是父节点下多少还是子节点变化都见面通报对该节点进行watch的客户端。因为EPHEMERAL类型节
点有一个分外重大之性状,就是客户端与服务器端连接断掉或者session过期就会使节点消失,那么在某个一个机器挂掉或者断链的时节,其对应之节点就会磨灭,然后集众多中所有对/APP1SERVERS进行watch的客户端都见面接通知,然后拿走时列表即可。

 澳门美高梅手机网站 12

 

Zookeeper 如何落实 Leader Election,也不怕是选出一个 Master
Server;另外有一个以场景就是是集群选master,一旦master挂掉能够及时会于slave中选出一个master,实现步骤和前者一样,只是机器当起步之
时候在APP1SERVERS创建的节点类型变为EPHEMERAL_SEQUENTIAL类型,这样每个节点会自动为编号

  1. zk.create(“/testRootPath/testChildPath1″,”1”.getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);  
  2.   
  3. zk.create(“/testRootPath/testChildPath2”,“2”.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);  
  4.   
  5. zk.create(“/testRootPath/testChildPath3″,”3”.getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);  
  6.   
  7. zk.create(“/testRootPath/testChildPath4″,”4”.getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);  
  8.   
  9. System.out.println(zk.getChildren(“/testRootPath”,false));  
  10.   
  11. 打印结果:[testChildPath10000000000,testChildPath20000000001, testChildPath40000000003, testChildPath30000000002]  

确定编号最小的呢master,所以当我们针对SERVERS节点做监控之时节,得到服务器列表,只要具备集群机器逻辑认为最好小数码节点吧master,那么master就被挑选来,而这master宕机的时光,相应的znode会消失,然后新的服务器列表就吃推送到客户端,然后每个节点逻辑认为绝小数码节点吧master,这样就是完了动态master选举。

HtmlElement
formLogin = webBrowser.Document.Forms[“loginForm”];
//……
formLogin.InvokeMember(“submit”);
正文之所以没有推荐这种方式,是盖本之网页,很多且以submit按钮上加加onclick事件,以对交付的内容做顶核心的说明。如果一直动用form的

下场景4:共享锁

共享锁在同一个进程面临酷爱实现,但是当跳进程要当不同 Server
之间便坏实现了。Zookeeper
却坏容易实现这个功能,实现方式啊是待获得锁的 Server 创建一个
EPHEMERAL_SEQUENTIAL 目录节点,然后调用
getChildren方法取得当前之目录节点列表中极小之目录节点是不是就是是团结创造的目节点,如果正是自己创立的,那么它便抱了此锁,如果非是那么其就调用
exists(String path, boolean watch) 方法并监控 Zookeeper
上目录节点列表的变化,一直到好创建的节点是列表中尽小数码的目录节点,从而赢得锁,释放锁死简单,只要去前面它好所开创的目节点就行了。

澳门美高梅手机网站 13

 

submit方法,这些验证代码就得不交实践,有或会见唤起错误。

应用场景5: 队列管理

Zookeeper
可以拍卖两种档次的阵:当一个队的积极分子还集中时,这个队列才可用,否则一直等所有成员至,这种是联合队列;队列按照
FIFO 方式展开入队与出队操作,例如落实生产者和顾客模型

创造一个父目录 /synchronizing,每个成员都监控目录 /synchronizing/start
是否在,然后每个成员还入此队(创建/synchronizing/member_i
的旋目录节点),然后每个成员取得 / synchronizing
目录的具有目录节点,判断 i
的价值是否早已是成员的个数,如果低于成员个数等 /synchronizing/start
的起,如果都相当于就创办 /synchronizing/start。

澳门美高梅手机网站 14

 

Study Case 3:查找并选择文本

二十五、总结

Zookeeper 作为 Hadoop 项目面临的一个子项目,是 Hadoop
集群管理之一个必备的模块,它主要用来支配集众多被之多少,如她管理
Hadoop 集众多被的 NameNode,还有 Hbase 中 Master Election、Server
之间状态并等。

Zoopkeeper提供了同等模拟好好的分布式集群管理之机制,就是它这种根据层次型的目录树的数据结构,并对准培养被之节点开展实用管理,从而可以计划来各式各样的分布式的数据管理型

转载:http://blog.csdn.net/l1028386804/article/details/52226265

这次咱们盼望实现一个以及IE一模一样的追寻功能,以对Web页面内之契进行搜寻。

文本查找要依靠TextRange对象的findText方法。但是,.Net里连从未此目标。这是因,.Net
2.0供的HtmlDocument,HtmlWindow,

HtmlElement等类,只不过是针对性原本mshtml这个COM组件的匪完封装,只提供了mshtml的片机能。所以广大辰光,我们还是要倚重mshtml来贯彻自我

曹需要的职能。好以这些.Net类都提供了DomDocument这个特性,使得我们特别轻把.Net对象转换为COM对象下。下面的代码演示了什么样寻找Web页面

的文本。
(需要添加mshtml的援,并累加using mshtml;)

    public partial class SearchDemo : Form
     {
        // 建立一个找用之TextRange(IHTMLTxtRange接口)
        private IHTMLTxtRange searchRange = null;
        public SearchDemo()
         {
             InitializeComponent();
         }

       
private void btnSearch_Click(object sender, EventArgs e)
         {
            // Document的DomDocument属性,就是该目标中的COM对象。
             IHTMLDocument2 document =
(IHTMLDocument2)webBrowser.Document.DomDocument;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == “”)
                return;

           
//
IE的寻逻辑就是,如果生选区,就起即选区开始+1许符处开始查找;没有底话语就由页面最初开始查找。
            //
这个逻辑其实是发接触未怪合适的,我们这里并非管,和IE一致即可。
            if (document.selection.type.ToLower() != “none”)
             {
                 searchRange =
(IHTMLTxtRange)document.selection.createRange();
                 searchRange.collapse(true);
                 searchRange.moveStart(“character”, 1);
             }
            else
             {
                 IHTMLBodyElement body =
(IHTMLBodyElement)document.body;
                 searchRange = (IHTMLTxtRange)body.createTextRange();
             }

           
// 如果找到了,就选(高亮显示)该要字;否则弹出信息。
            if (searchRange.findText(keyword, 1, 0))
             {
                 searchRange.select();
             }
            else
             {
                 MessageBox.Show(“已找到文档结尾。”);
             }
         }
     }

暨是结束,简单的索就来定了。至于替换功能,看了产一个例,我深信不疑你不怕得触类旁通轻松打定矣。

Study Case 4:高亮显示

落得一个例子中我们学会了查找文本——究跟到底,对Web页面还是就读不写。那么,如果说如将具备的追寻结果高亮显示为?我们飞速会想到将装有匹

配的仿颜色、背景改一下哪怕好了。
先是想到的或者是直修改HTML文本吧……但是,与SourceCode的高亮显示不同,我们要而独自需要高亮页面被的公文部分。HTML标签、脚本代码

等等是绝不该去改变的。因此我们无能够拿一切页面的Source
Code读进来然后replace,那样有磨损HTML文件结构的恐怕;我们不得不于会分离有

文本及其他情节(标签,脚本……)的前提下进行。

具体方法有诸多,下面提供零星独比较简单的计。

方法一:使用TextRange(IHTMLTxtRange)
来了齐一个Case的底蕴,相信大家立即会想到以TextRange。没错,TextRange除了提供查找方法之外,还提供了一个pasteHTML方法,以指定的HTML

文本替换当前TextRange中的情。代码片断如下:

   
public partial class HilightDemo : Form
     {
        // 定义高亮显示力量的签。
        string tagBefore = “<span
style=’background-color:yellow;color:black’>”;
        string tagAfter = “</span>”;

       
// ……

       
private void btnHilight_Click(object sender, EventArgs e)
         {
             HtmlDocument htmlDoc = webBrowser.Document;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == “”)
                return;

           
object oTextRange = htmlDoc.Body.InvokeMember(“createTextRange”);

            
mshtml.IHTMLTxtRange txtrange = oTextRange as
mshtml.IHTMLTxtRange;

           
while (txtrange.findText(keyword, 1, 4))
             {
                try
                 {
                     txtrange.pasteHTML(tagBefore + keyword +
tagAfter);
                 }
                catch { }
                 txtrange.collapse(false);
             }
         }
     }

※这段代码里得到IHTMLTxtRange的法以及方的例证稍小不与,其实所谓条条大路通罗马,本质是千篇一律的。

主意二:使用DOM(文档对象模型)
将HTML文档解析为DOM,然后遍历每个节点,在里面搜关键字并开展相应替换处理即可。

   
public partial class HilightDemo : Form
     {
        //……

       
private void btnHilight_Click(object sender, EventArgs e)
         {
             HTMLDocument document =
(HTMLDocument)webBrowser.Document.DomDocument;
             IHTMLDOMNode bodyNode =
(IHTMLDOMNode)webBrowser.Document.Body.DomElement;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == “”)
                return;

            
HilightText(document, bodyNode, keyword);
         }

       
private void HilightText(HTMLDocument document, IHTMLDOMNode node,
string keyword)
         {
            // nodeType = 3:text节点
            if (node.nodeType == 3)
             {
                string nodeText = node.nodeValue.ToString();
                // 如果找到了要字
                if (nodeText.Contains(keyword))
                 {
                     IHTMLDOMNode parentNode = node.parentNode;
                    //
将根本字当分隔符,将文件分离,并逐条添加到原text节点的父节点
                    string[] result = nodeText.Split(new string[] {
keyword }, StringSplitOptions.None);
                    for (int i = 0; i < result.Length – 1; i++)
                     {
                        if (result[i] != “”)
                         {
                             IHTMLDOMNode txtNode =
document.createTextNode(result[i]);
                             parentNode.insertBefore(txtNode, node);
                         }
                         IHTMLDOMNode orgNode =
document.createTextNode(keyword);
                         IHTMLDOMNode hilightedNode =
(IHTMLDOMNode)document.createElement(“SPAN”);
                         IHTMLStyle style =
((IHTMLElement)hilightedNode).style;
                         style.color = “black”;
                         style.backgroundColor = “yellow”;
                         hilightedNode.appendChild(orgNode);

                        
parentNode.insertBefore(hilightedNode, node);
                     }
                    if (result[result.Length – 1] != “”)
                     {
                             IHTMLDOMNode postNode =
document.createTextNode(result[result.Length – 1]);
                             parentNode.insertBefore(postNode, node);
                     }
                     parentNode.removeChild(node);
                 } // End of nodeText.Contains(keyword)
             }
            else
             {
                // 如果非是text节点,则递归搜索其子节点
                 IHTMLDOMChildrenCollection childNodes = node.childNodes
as IHTMLDOMChildrenCollection;
                foreach (IHTMLDOMNode n in childNodes)
                 {
                     HilightText(document, n, keyword);
                 }
             }
         }
     }

点的点滴截代码都是为清晰易掌握而简单得无可知再简单的,有多地方深无到家。比如,没考虑到如何由高亮显示状态恢复;也没轻重写匹配等等。

本来,掌握了规律之后相信这些都未会见尽为难。

当即简单种办法各发利害:
以TextRange较轻量迅速,而且发生一个特长,就是得把超过标签(Tag)的要字挑出来。例如,有这般一段落HTML:

<b>Hel</b>lo
World!
先期管作者出于什么目的让Hel三只假名成为粗体,总之显示在页面上的凡同样句“Hello
World!”。在我们愿意高亮页面被之“Hello”这个主要字时

,如果因此DOM分析的口舌,会汲取含有“Hel”的<b>节点和文书节点“lo
World!”两独节点,因此无法将该挑出来。而TextRange则会正确识别,将那只要

置为高亮。因此为堪说TextRange是单独同文书有关,和HTML语法结构无关的对象。

而,TextRange也来夫致命弱点,加亮容易,反向的说话就是杀麻烦。换句话说,去除高亮显示的时不可知再就此TextRange,而得以另外方法。

倘若DOM方法虽然正好相反,
由于DOM的树状结构特点,虽然不克(或者深麻烦)跨越Tag搜索关键字,但是去高亮显示并无麻烦。

Study
Case 5:与剧本的互操作

于Case
1当中,我们已经看到,Web页面的HTML元素的轩然大波,可以由Windows
Form端来响应,可以在某种程度上作是Web页面调用WinForm;那么反过

来,WinForm除了可一直看Web页面的HTML元素之外,能否调用Web页面里的各种Script呢?

第一是调用Web页面的脚本中一度定义好之函数。假设HTML中犹如下Javascript:

function
DoAdd(a, b) {
    return a + b;
}
那,我们若于WinForm调用其,只需要如下代码即可:

object
oSum = webBrowser.Document.InvokeScript(“DoAdd”, new object[] { 1, 2
});
int sum = Convert.ToInt32(oSum);
辅助,如果我们怀念实行同一段Web页面中原本没有底脚本,该怎么开吗?这次.Net的近乎没有供,看来还要依赖COM了。IHTMLWindow2可以以随机的字符

出错作为脚本代码来推行。

string
scriptline01 = @”function ShowPageInfo() {“;
string scriptline02 = @”      var numLinks = document.links.length; “;
string scriptline03 = @”      var numForms = document.forms.length; “;
string scriptline04 = @”      var numImages = document.images.length;
“;
string scriptline05 = @”      var numScripts = document.scripts.length;
“;
string scriptline06 = @”      alert(‘网页的统计结果:\r\n链接数:’ +
numLinks + “;
string scriptline07 = @”         ‘\r\n表单数:’ + numForms + “;
string scriptline08 = @”         ‘\r\n图像数:’ + numImages + “;
string scriptline09 = @”         ‘\r\n脚本数:’ + numScripts);}”;
string scriptline10 = @”ShowPageInfo();”;

string
strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 +
scriptline05 +
                    scriptline06 + scriptline07 + scriptline08 +
scriptline09 + scriptline10;

IHTMLWindow2
win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow;
win.execScript(strScript,
“Javascript”);http://www.xmlasp.net/n1670c13.aspx

http://hi.baidu.com/motiansen/blog/item/9e99a518233ca3b24aedbca9.html

动ObjectForScripting属性,可启用 WebBrowser 控制项所装载的 Web
网页和富含 WebBrowser 控制项的应用程式间的报道。
这个特性可让您做动态超文字标记语言 (DHTML)
程式码与用户端应用程式程式码。
点名为这特性之物件可被 Web 网页指令码做吗 window.external
物件,这个物件是以存取主应用程式而提供的内建 DOM 物件。

private void btnScriptEvent_Click(object sender, EventArgs e)
{
           webBrowser1.ObjectForScripting = this;

           
string szWebBrowserText = “<html>” +
                “<head>” +
                “<title></title>”+                   
                 “</head>” +
               “<body onkeydown=\”KeyDown()\”
oncontextmenu=\”event.returnValue=false\”>”+
              
               “Please enter your name:<br/>”+
                 “<input type=’text’ name=’Name’/><br/>”+
                 “<font
onClick=’window.external.ClickEvent(Name.value)’>Click
Here</font>”+
                “</body></html>”;

             webBrowser1.DocumentText = szWebBrowserText;
         }
        public void ClickEvent(string userName)
        {
            // Simply echo out the name that the user typed in the input
box of the HTML page
            if
(System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft
== true)
                 MessageBox.Show(“Hello ” + userName, “Managed Web
Browser Sample”, MessageBoxButtons.OK,

MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign |
MessageBoxOptions.RtlReading);
            else
                 MessageBox.Show(“Hello ” + userName, “Managed Web
Browser Sample”, MessageBoxButtons.OK,

MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1);

        
}

 

=
szWebBrowserText;

==================================
特别类型 条件
ArgumentException
装该属性时指定的价为非公共类型的实例。


或 –

安该属性时指定的价也非
COM 可见的品类的实例。有关重新多信息,请参见
Marshal.IsTypeVisibleFromCom。

备注
运该属性启用 WebBrowser 控件承载的网页和分包 WebBrowser
控件的应用程序之间的通信。使用该属性可以用动态 HTML (DHTML)
代码与客户端

应用程序代码集成在一块儿。为该属性指定的对象可是作
window.external 对象(用于主机访问的放权 DOM 对象)用于网页脚本。

足以这属性设置也盼该官性质和道可用以脚本代码的另
COM 可见的对象。可以透过运用 ComVisibleAttribute
对类进行标记使该改为

COM
可见的切近。

一经使自客户端应用程序代码调用网页中定义的函数,请用可自从
Document 属性检索的 HtmlDocument 对象的 HtmlDocument.InvokeScript
方法。

示例
脚的代码示例演示如何使 ObjectForScripting
属性。在该示例中,ObjectForScripting 属性被装置也当前窗体。


using
System;
using System.Windows.Forms;
using System.Security.Permissions;

[PermissionSet(SecurityAction.Demand,
Name=”FullTrust”)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{
    private WebBrowser webBrowser1 = new WebBrowser();
    private Button button1 = new Button();

   
[STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }

   
public Form1()
    {
        button1.Text = “call script code from client code”;
        button1.Dock = DockStyle.Top;
        button1.Click += new EventHandler(button1_Click);
        webBrowser1.Dock = DockStyle.Fill;
        Controls.Add(webBrowser1);
        Controls.Add(button1);
        Load += new EventHandler(Form1_Load);
    }

   
private void Form1_Load(object sender, EventArgs e)
    {
        webBrowser1.AllowWebBrowserDrop = false;
        webBrowser1.IsWebBrowserContextMenuEnabled = false;
        webBrowser1.WebBrowserShortcutsEnabled = false;
        webBrowser1.ObjectForScripting = this;
        // Uncomment the following line when you are finished
debugging.
        //webBrowser1.ScriptErrorsSuppressed = true;

       
webBrowser1.DocumentText =
            “<html><head><script>” +
            “function test(message) { alert(message); }” +
            “</script></head><body><button ” +
            “onclick=\”window.external.Test(‘called from script
code’)\”>” +
            “call client code from script code</button>” +
            “</body></html>”;
    }

   
public void Test(String message)
    {
        MessageBox.Show(message, “client code”);
    }

   
private void button1_Click(object sender, EventArgs e)
    {
        webBrowser1.Document.InvokeScript(“test”,
            new String[] { “called from client code” });
    }

}


// Navigates to the URL in the address box when
// the ENTER key is pressed while the ToolStripTextBox has focus.
private void toolStripTextBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        Navigate(toolStripTextBox1.Text);
    }
}

//
Navigates to the URL in the address box when
// the Go button is clicked.
private void goButton_Click(object sender, EventArgs e)
{
    Navigate(toolStripTextBox1.Text);
}

//
Navigates to the given URL if it is valid.
private void Navigate(String address)
{
    if (String.IsNullOrEmpty(address)) return;
    if (address.Equals(“about:blank”)) return;
    if (!address.StartsWith(“http://”) &&
        !address.StartsWith(“https://”))
    {
        address = “http://” + address;
    }
    try
    {
        webBrowser1.Navigate(new Uri(address));
    }
    catch (System.UriFormatException)
    {
        return;
    }
}

//
Updates the URL in TextBoxAddress upon navigation.
private void webBrowser1_Navigated(object sender,
    WebBrowserNavigatedEventArgs e)
{
    toolStripTextBox1.Text = webBrowser1.Url.ToString();
}

====================================================================================
HtmlElement.DomElement 属性
属性值
素的 COM IUnknown 指针,可以以那个强制转换为 HTML
元素接口中之之一一个接口,如 IHTMLElement。
备注
HtmlElement 也 Internet Explorer 文档对象模型 (DOM)
的包,它是故组件对象模型 (COM) 编写而成。如果欲看基础 COM
接口中之免明

特性或措施(如
IHTMLElement),可以应用此目标查询其。

为以非托管接口,需要以
MSHTML 库 (mshtml.dll) 导入到应用程序中。但是,也可动用 Invoke
方法执行不公开属性与艺术。

示例
下的代码示例使用非托管接口获取当前选定的文本,并利用由用户选择的 URL
将那个更换为超越链接。编写这代码时,假得窗体拥有一个叫吧

WebBrowser1
的 WebBrowser 控件,并使已经坐引用的款型拿非托管 MSHTML
库添加到品种遭到。

C#
复制代码
private void CreateHyperlinkFromSelection()
{
    if (webBrowser1.Document != null)
    {

       
mshtml.IHTMLDocument2 iDoc =
(mshtml.IHTMLDocument2)webBrowser1.Document.DomDocument;

       
if (iDoc != null)
        {
            mshtml.IHTMLSelectionObject iSelect = iDoc.selection;
            if (iSelect == null)
            {
                MessageBox.Show(“Please select some text before using
this command.”);
                return;
            }

           
mshtml.IHTMLTxtRange txtRange =
(mshtml.IHTMLTxtRange)iSelect.createRange();

           
// Create the link.
            if (txtRange.queryCommandEnabled(“CreateLink”))
            {
                Object o = null;
                txtRange.execCommand(“CreateLink”, true, o);
            }
        }
    }
}

http://msdn.microsoft.com/zh-cn/library/system.windows.forms.htmlelement.domelement(VS.80).aspx

===========================================================
行使webbrowser和mshtml.dll获取网页源代码的题目
悬赏分:100 – 解决时:2006-7-19 16:52
我使用C#做一个主次,其中提到到一个意义,在输入指定网址之后,需要得到html源代码进行辨析。
自身动用了webbrowser控件和mshtml.dll
而只能取得到平凡页面的源代码
设采集带有cookie控制的页面就见面败。
哪位能帮忙拉?

自己对webbrowser的运用并无老知,这个空间是否能一直沾html代码呢?
mshtml.dll说是可以针对html代码进行辨析。但怎样运用?

生哪个能够吃有证明与源代码,感激不尽。
题材上:我利用以下代码获取webbrowser中之html,但是有只深想得到之题材。我老是点为止按钮都见面发现文本框中显示的html都未都,而且还将同

页面的html显示了无数全体。如果页面内容比较充分则会滋生程序非常掉。
为什么吗?
提问者: willgo – 助理 二级 最佳答案
private void button1_Click(object sender, System.EventArgs e) {
object
url=\”http://www.google.com\\”;
object nothing=null;
this.axWebBrowser1.Navigate2(ref url,ref nothing,ref nothing,ref
nothing,ref nothing);
this.axWebBrowser1.DownloadComplete+=new
System.EventHandler(this.button2_Click);
}

private
void button2_Click(object sender, System.EventArgs e) {
this.textBox1.Text=\”\”;
mshtml.IHTMLDocument2
doc=(mshtml.IHTMLDocument2)this.axWebBrowser1.Document;
mshtml.IHTMLElementCollection all=doc.all;
System.Collections.IEnumerator enumerator=all.GetEnumerator();
while(enumerator.MoveNext() && enumerator.Current!=null)
{
mshtml.IHTMLElement element=(mshtml.IHTMLElement)(enumerator.Current);
if(this.checkBox1.Checked==true)
{
this.textBox1.Text+=\”\\r\\n\\r\\n\”+element.innerHTML;
}
else
{
this.textBox1.Text+=\”\\r\\n\\r\\n\”+element.outerHTML;
}
}
}

=============
瞩目
本例程中以了一个勿公开之GUID,其于明天底体系中得以发变动。

  1、定义
IOleCommandTarget 接口

  为定义一个.NET接口以博得有关一个COM接口的参阅,请遵下列步骤:

  1)
赋予.NET接口相应的COM接口的GUID值;

  2)
包含对接口中具有方的花色声明;

  3)
包含对Mshtml.dll和Shdocvw.dll文件的参考,在Visual C#
.NET工程被操作,请遵:

  A.
以类型菜单下单击“添加引用”;

  B.
单击“COM” 选项卡;

  C.
双击“Microsoft HTML Object Library” 和“Microsoft Internet Controls”。

转:http://www.360doc.com/content/10/1006/12/3722251_58785246.shtml

发表评论

电子邮件地址不会被公开。 必填项已用*标注