7.view Blog的实现2--CometActor
在viewblog方法中,当findAll方法返回一个有值的List时,使用了一个<lift:comet><lift:comet/>标签,这个标签的执行结果是,首先显示Loading...,然后刷新成指定用户的博客内容列表。如果在另一个浏览器去创建新的博客时,这个列表将自动刷新。
为了理解这个过程,需要了解Actor和Comet这两个概念。
i)Actor
Actor是scala用来简化并发和多线程开发的模型,在《Programming In Scala》Ch.30有较为详细的介绍。简单总结几点现在需要了解的内容
1)使用Actor需要继承scala.actors.Actor,并实现act方法,actor通过start()方法开始运行。
2)actor之间通过发送消息进行交互,发送消息通常的方法是! (!是Actor中定义的方法,类似的还有!!,!?)
3)接受消息的actor通常使用receive、react等方法从mailbox中提取消息并处理,这些方法的运行往往在loop中完成,这两个方法接受的参数是以下形式
这是一种Case sequences as partial functions的语法(《Programming In Scala》ch15.7 P314)
ii)Comet
“Comet 是一种新的 Web 应用架构。基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求。Comet 架构非常适合事件驱动的 Web 应用。”具体可参考[url]http://en.wikipedia.org/wiki/Comet_(programming)[/url]。《The Definitive Guide To Lift》Ch.9(P168)也有一些介绍
在liftweb中Comet是通过actor来实现的;lift提供了CometActor trait,使用Comet时需要继承CometActor,并实现一些方法。
我们来看例子中的代码
type参数告诉lift使用哪个ComitActor类,在这里是com.hellolift.comet.DynamicBlogView;name是定义在CometActor中的属性,这里将用来传递用户id。
<lift:comet/>里内嵌了一个<blog:view/>标签,看一下DynamicBlogView中这个标签有关的的代码
这里定义了在这个<lift:comet>标签中用到的节点的前缀"blog"
这里定义了一个render方法,显然标签中的view,会被这里的view对应的节点所替代。
为了比较容易理解comet的执行过程,我简单总结了一下DynamicBlogView执行过程中的一些流程,很多地方不够准确,只是起到示意作用
[img]http://dl.iteye.com/upload/attachment/160729/d8c8f546-db80-38f1-a666-638b6c793399.jpg[/img]
从流程可以看到从comet这个snippet到DynamicBlogView这个CometActor实例的运行过程,[b]在snippet的render过程中启动了DynamicBlogView的start方法,在act loop中将调用lowPriority方法来处理消息。在有消息产生之前,还调用了localSetup进行初始化的工作,在snippet的render过程和消息处理的过程中都会调用render方法来产生页面内容。[/b]
理解这个comit主要就是理解各消息的发送和处理过程
1. localSetup中,向BlogCache发送一个同步(!?)的AddBlogWatcher消息,
2. BlogCache 在loop中处理这个消息根据用户id,加载博客列表并通过BlogUpdate消息返回给DynamicBlogView,同时把这个DynamicBlogView记录在session中(观察者模式),并在以后内容发生变化时发送通知消息。
3. DynamicBlogView 处理 BlogUpdate消息,将blog内容记录,供render展示。
4. 当其他增删改的操作改变博客内容时,BlogCache 将再次向DynamicBlogView 发送BlogUpdate消息,DynamicBlogView 在lowPriority中处理消息记录并刷新页面内容。
(终于把这个过程说完了,喘口气,其他的细节等有心情的时候再说了)
疑问:reRender方法的参数是什么作用,看代码没能跟下去求助一下
在viewblog方法中,当findAll方法返回一个有值的List时,使用了一个<lift:comet><lift:comet/>标签,这个标签的执行结果是,首先显示Loading...,然后刷新成指定用户的博客内容列表。如果在另一个浏览器去创建新的博客时,这个列表将自动刷新。
为了理解这个过程,需要了解Actor和Comet这两个概念。
i)Actor
Actor是scala用来简化并发和多线程开发的模型,在《Programming In Scala》Ch.30有较为详细的介绍。简单总结几点现在需要了解的内容
1)使用Actor需要继承scala.actors.Actor,并实现act方法,actor通过start()方法开始运行。
2)actor之间通过发送消息进行交互,发送消息通常的方法是! (!是Actor中定义的方法,类似的还有!!,!?)
3)接受消息的actor通常使用receive、react等方法从mailbox中提取消息并处理,这些方法的运行往往在loop中完成,这两个方法接受的参数是以下形式
react {
case (name: String, actor: Actor) => actor ! getIp(name)
case msg => println("Unhandled message: " + msg)
}
这是一种Case sequences as partial functions的语法(《Programming In Scala》ch15.7 P314)
ii)Comet
“Comet 是一种新的 Web 应用架构。基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求。Comet 架构非常适合事件驱动的 Web 应用。”具体可参考[url]http://en.wikipedia.org/wiki/Comet_(programming)[/url]。《The Definitive Guide To Lift》Ch.9(P168)也有一些介绍
在liftweb中Comet是通过actor来实现的;lift提供了CometActor trait,使用Comet时需要继承CometActor,并实现一些方法。
我们来看例子中的代码
<lift:comet type="DynamicBlogView" name={toLong(S.param("id")).toString}>
<blog:view>Loading...</blog:view>
</lift:comet>
type参数告诉lift使用哪个ComitActor类,在这里是com.hellolift.comet.DynamicBlogView;name是定义在CometActor中的属性,这里将用来传递用户id。
<lift:comet/>里内嵌了一个<blog:view/>标签,看一下DynamicBlogView中这个标签有关的的代码
override def defaultPrefix = Full("blog")
这里定义了在这个<lift:comet>标签中用到的节点的前缀"blog"
// render draws the content on the screen.
def render = {
bind("view" -> <span>{blog.flatMap(e => _entryview(e))}</span>)
}
这里定义了一个render方法,显然标签中的view,会被这里的view对应的节点所替代。
为了比较容易理解comet的执行过程,我简单总结了一下DynamicBlogView执行过程中的一些流程,很多地方不够准确,只是起到示意作用
[img]http://dl.iteye.com/upload/attachment/160729/d8c8f546-db80-38f1-a666-638b6c793399.jpg[/img]
从流程可以看到从comet这个snippet到DynamicBlogView这个CometActor实例的运行过程,[b]在snippet的render过程中启动了DynamicBlogView的start方法,在act loop中将调用lowPriority方法来处理消息。在有消息产生之前,还调用了localSetup进行初始化的工作,在snippet的render过程和消息处理的过程中都会调用render方法来产生页面内容。[/b]
理解这个comit主要就是理解各消息的发送和处理过程
1. localSetup中,向BlogCache发送一个同步(!?)的AddBlogWatcher消息,
2. BlogCache 在loop中处理这个消息根据用户id,加载博客列表并通过BlogUpdate消息返回给DynamicBlogView,同时把这个DynamicBlogView记录在session中(观察者模式),并在以后内容发生变化时发送通知消息。
3. DynamicBlogView 处理 BlogUpdate消息,将blog内容记录,供render展示。
4. 当其他增删改的操作改变博客内容时,BlogCache 将再次向DynamicBlogView 发送BlogUpdate消息,DynamicBlogView 在lowPriority中处理消息记录并刷新页面内容。
(终于把这个过程说完了,喘口气,其他的细节等有心情的时候再说了)
疑问:reRender方法的参数是什么作用,看代码没能跟下去求助一下
def reRender(sendAll: Boolean)