云联天下首页 |  登陆 |  注册 |  密码找回 |  关于我们 | 加入收藏 
首页技术资料网站建设→DotText源码阅读(7) --Pingback/TrackBack 【字号: 】 【背景色 杏仁黄 秋叶褐 胭脂红 芥末绿 天蓝 雪青 灰 银河白(默认色)

DotText源码阅读(7) --Pingback/TrackBack

网址来源:http://www.kehui.net发布时间: 2006-12-07 00:00:16
博客这种服务的区别于论坛和所谓文集网站,很大程度上我认为是由于pingback/trackback的存在,使得博客这种自媒体有可以延展加入SNS的要素。所以分析博客程序,我们需要了解这种协议以及协议的实施细节。

       在dottext的源代码中,在发表作品中,我们可以看到有pingback协议的支持,同时在web services的实现中,有trackback协议的实现。至于什么是piongback/trackback协议,google下应当可以找到,也不用我费口舌。

              通过              <HttpHandlerpattern="/(?:admin)"type="Dottext.Web.UI.Handlers.BlogExistingPageHandler, Dottext.Web"handlerType="Factory"/>

的映射,使得我们访问每一个blog的admin目录时候,都会UrlRewrite到dottexwebadmin目录下的相对应aspx文件(参考前面部分),其中在发表post的时候,我们看到是这样一个调用关系:

       private void UpdatePost()

         {   

              if(Page.IsValid)

              {

                   string successMessage = Constants.RES_SUCCESSNEW;

                   try

                   {

                       Entry entry = new Entry(EntryType);

 

                        entry.Title = txbTitle.Text;

                        entry.Body = Globals.StripRTB(ftbBody.Text,Request.Url.Host);

                      

                        entry.BlogID = Config.CurrentBlog(Context).BlogID;

                      

                       if (PostID > 0)

                       {//是更新操作

                            successMessage = Constants.RES_SUCCESSEDIT;

                            entry.DateUpdated = DateTime.Now;//BlogTime.CurrentBloggerTime;

                            entry.EntryID = PostID;

                           

                            Entries.Update(entry);

                           

                       }

                       else

                       {//新建操作

                            entry.DateCreated = DateTime.Now;//BlogTime.CurrentBloggerTime;

                            PostID = Entries.Create(entry);       

                       }


                   }

                   catch(Exception ex)

                   {           }

                   finally

                   {            }

              }

     }

     Entries.Create(entry);是这样的:

         public static int Create(Entry entry, int[] CategoryIDs)

         {

              HandlerManager.PreCommit(entry,ProcessAction.Insert);            

              int result = DTOProvider.Instance().Create(entry,CategoryIDs);             

              if(result > 0)

              {

                   HandlerManager.PostCommit(entry,ProcessAction.Insert);                

              }

              return result;

     }

     最终的数据存储试调用DTOProvider也就是DataDTOProvider 最终是落到 SqlDataProvider 来实现数据存储操作。但是我们注意到 HandlerManager.PostCommit(entry,ProcessAction.Insert);     这个操作。仔细看看:

     HandlerManager 是一个关于Entry操作类的包装类(wapper class),PreCommit是这样定义的:

          Process(ProcessState.PreCommit,e,pa);

     而Process是这样读取web.config的

     public static void Process(ProcessState ps, Entry e, ProcessAction pa)

         {     //Do we have factories? 在疑惑是否该用工厂模式呢

              EntryHandler[] hanlers = Config.Settings.EntryHandlers;     //这是反序列化哦,这里的Config是Dottext.Framework.Configuration.Config

              if(e != null && hanlers != null)

              {     //walk the entries 遍历全部处理例程

                   for(int i = 0; i<hanlers.Length; i++)

                   {

                        EntryHandler handler = hanlers[i];

                        if(ShouldProcess(ps,handler,e.PostType,pa))

                       {

                            IEntryFactoryHandler ihandler = handler.IEntryFactoryHandlerInstance;                           

                            //Call the IEntryFactoryHandler configure method. This gives async items a chance to "ready" themselves

                            //before leaving the main thread and entering the managed queue.

                            ihandler.Configure();

                            if(handler.IsAsync)

                            {//Add factory to managed queue.

                                 EntryHanlderQueue.Enqueue(ihandler,e);

                            }

                            else

                            {

                                 ihandler.Process(e);

                            }

                       }

                      

                   }

              }

         }

ShouldProcess 是判断是预提交还是已经提交post,决定是否应该进行handler的实例化,如果是已经提交的Post,我们需要进行handler.IEntryFactoryHandlerInstance;      IentryFactoryHandlerInstance最终是通过

ihandler = (IEntryFactoryHandler)Activator.CreateInstance(Type.GetType(this.ItemType));

来实例化数组元素的().

经过实例化后,就可以执行了。此时根据 handler.IsAsync 的属性,决定是允许 EntryHanlderQueue.Enqueue(ihandler,e); 加入队列,还是马上处理

ihandler.Process(e);.

对于可以异步执行的静态函数 Enque 处理:

public static void Enqueue(IEntryFactoryHandler factory, Entry e)

         {

              EntryHanlderQueue ehq = new EntryHanlderQueue(factory,e);

              ManagedThreadPool.QueueUserWorkItem(new WaitCallback(ehq.Enqueue));

     }

构造一个实例,然后加入线程队列进行任务排队。线程管理暂不讨论。我们看看这几个EntryHandler.

TrackBack Handler是如何处理的呢?

public void Process(Dottext.Framework.Components.Entry e)

         {

              //Get a list of links from the current post

              StringCollection links = TrackHelpers.GetLinks(e.Body);

              if(links != null && links.Count > 0)

              {

                   //Instantiate our proxy

                   TrackBackNotificationProxy proxy = new TrackBackNotificationProxy();

                  

                   //Walk the links

                   for(int i = 0; i<links.Count; i++)

                   {

                       string link = links[i];

                       //get the page text

                       string pageText = BlogRequest.GetPageText(link,e.Link);

                        if(pageText != null)

                       {

                            try

                            {

                                 string desc = null;

                                 if(e.HasDescription)

                                 {

                                     desc = e.Description;

                                 }

                                 else

                                 {

                                      desc=string.Format("TrackBack From:{0}",e.Link);

                                      

                                 }   

desc = regexStripHTML.Replace(e.Body,string.Empty);

                                      if(desc.Length > 100)

                                     {

                                          int place = 100;

                                          int len = desc.Length-1;

                                          while(!Char.IsWhiteSpace(desc[place]) && i < len)

                                          {

                                               place++;

                                          }

                                          desc = string.Format("{0}...",desc.Substring(0,place));

                                     }

                                 }

                                 //attempt a trackback.

                            proxy.TrackBackPing(pageText,link,e.Title,e.Link,e.Author,desc);                           

                            }

                            catch(Exception ex)

                            {                                 Logger.LogManager.CreateExceptionLog(ex,string.Format("Trackback Failure: {0}",link));

                            }

                       }

                   }

              }

     }

 TrackHelpers.GetLinks 会分析Entry.Body字符串,获得post的全部href连结,也就是对外引用部分,这个TrackBack利用proxy.TrackBackPing(pageText,link,e.Title,e.Link,e.Author,desc); 将本文的对外引用通告刚刚获得的连接地址。

      
TrackBackPing :

    string pageText = BlogRequest.GetPageText(link,e.Link);会利用BlogRequest的http协议能力下载被引用地址的source code,然后 link为另外blog的地址,而e.Link为reffer,这是为了告知对方那个页面引用了link。经过安全解码后,获得了link的源代码,然后TrackBackPing会进行分析,找寻string sPattern = @"<rdf:w+s[^>]*?>(</rdf:rdf>)?";匹配的部分,分析出其中的引用通告地址。下一步就是利用SendPing(string trackBackItem, string parameters),向目标地址处post一个application/x-www-form-urlencoded"的数据。此即完成了一次trackBack.



  其他几个EntryHandler也是分同步和异步的,大家可以照此阅读。

    

    题外话:那些没有礼貌的实现pingback/Trackback的所谓blog,就不要妄自称自己为博客服务商(BSP)吧。






shanhe 

相关新闻
v Macromedia Flex 安装注册方法 2006-12-07 00:00:16
v 开源的数据库连接池 SQL Relay 介绍 2006-12-07 00:00:16
v 有趣人物为你讲述网站开发过程 2006-12-07 00:00:16
v apache中httpd.conf的中文件详解 2006-12-07 00:00:16
v 一个简单的tomcat部署方案 2006-12-07 00:00:16
v 7 Reasons Why Web Apps Fail 2006-12-07 00:00:16
v 7 More Reasons Why Web Apps Fail 2006-12-07 00:00:16
v 2006-5-20 SQL 外链接操作小结 inner join & left join & right join 2006-12-07 00:00:16
v The future of OO Javascript 2006-12-07 00:00:16
v The future of OO Javascript 2006-12-07 00:00:16
  最新新闻
智慧家居
智慧家居颠覆传统智能家居
智慧云谷让智能家居变成有智慧的
智慧云谷引领智慧家居新生活
科技改变生活 智慧云谷智慧家居系
智慧家居领航者,智慧云谷助你玩
智能家居如何赢得市场美誉度?
智慧云谷智慧家居:创业者有无限
WiFi智能家居你还在用?这样的智
互联网+助推智能家居产业
智慧云谷为您打造真正的智能家居
智能家居产业需要的不是单品,而
新家如何选择开关?智慧云谷iWis
智能传感器-世界首款“智”为你的
智慧云谷开关智能安防智能空气质
智能开关品牌,如何选择智能开关
秋季干燥,智慧家居温湿度传感器
传感器助力智慧家居 感知爱家
iWiscloud智能触摸开关缔造家居装

  最新帖子
 ※室内空气污染的危害及  [sensor]
 ※超声波风速传感器在生  [sensor]
 ※这么冷清  [gabc111]
 ※手机APP操作有问题  [ssy11407]
 ※智慧云谷智慧家居将在  [cici]
 ※上传下载  [cici]
 ※下载智慧家居  [apple2008]
 ※秋季干燥,智慧家居温  [apple2008]
 ※智慧家居紧扣热点 安全  [apple2008]
 ※办公大楼如何智慧化管  [apple2008]
 ※智慧云谷工业自控的优  [apple2008]
 ※传感器助力智慧家居 感  [apple2008]
 ※智能开关品牌,如何选  [apple2008]
 ※智慧云谷开关智能安防  [apple2008]
 ※没有专业人员,如何安  [apple2008]
 ※烟台智慧云谷董事长任  [apple2008]
 ※互联网+助推智能家居产  [apple2008]
 ※WiFi智能家居你还在用  [apple2008]
 ※智慧云谷智慧家居:创  [apple2008]
 ※智能家居如何赢得市场  [apple2008]
钯碳回收 硝酸银回收 银浆回收 银焊条回收 回收银浆 氯化钯回收 氯化钯回收 氧化钯回收 回收硝酸钯 钯水回收价格 海绵钯回收 钯炭回收价格 回收镀金板 深圳钯碳回收 镇江氯化钯回收 杭州钯浆回收 银浆回收多少钱 回收钯碳公司 硝酸银的价格 那里有回收金 氯化钯回收价格 江苏擦银布回收 硝酸银价格 德州钯粉回收 银铜回收 回收钯粉 回收铂碳催化剂 佛山钯碳回收 金盐回收价格 海绵钯回收 钯碳高价回收 钯回收价格 钯炭回收