`
witcheryne
  • 浏览: 1093183 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Pushlet学习(二) -- Pushlet CookBook部分翻译 + 注释

阅读更多

    这两天一直在研究Pushlet这个框架,查了很多资料还是没有理清楚pushlet的执行方式。今天细细的看了看Pushlet CookBook, 结合着自己的理解对这个文档进行了翻译,在翻译的过程中加了一些注释以便理解。

    由于个人能力有限,对文档翻译的还不够完善,在这里贴出来希望能够对刚开始接触Pushlet的人有所帮助。如果在文中出现的错误,还望大家指出,共同讨论以便完善。

    关于Pushlet的其他资源可以参考之前写的

     Pushlet 学习(一) 相关资料搜集(对Pushlet不太了解的话,建议先阅读者部分内容)


    在阅读Pushlet源码时也加了一些注释,希望对各位也有所帮助. 相关代码在附件中...  直接导入eclipse即可使用.由于这个工程创建的时候使用的是Eclipse Java Project的方式创建的,现在在tomcat无法运行,如果有什么好的方法还望告知。在这里先谢过了...

 

 

     Pushlets - Cookbook

 

Pushlet Doc 写道

1. Application Development

The Pushlet framework is basically a message exchange. One part of your application will be dealing with generating and sending messages (called Events) to the framework, the other part (usually the browser) will be receiving messages. The new (v2) protocol also allows clients to both publish and subscribe to events. The common two tasks for application development involve (1) creating the message sources and (2) developing the receivers. As we shall see the Pushlet framework has various possibilities in order to develop senders and receivers. Since interfacing may even be done entirely through HTTP (and XML) you may develop an application in any programming/scripting language that supports HTTP.
 


    Puhslet基本上算是一个信息交互框架。你程序的一部分将会处理向框架 cenerating 和 sending messages(called Events),其他部分则将会会得到messages。这个信息的协议允许客户端能够publisht和 subscribe events。这样需要程序有两个任务被调用:

1. 创建消息源 ; 【注: 在pushlet框架中有一个sources.properties文件, 创建的消息源必须在这个文件中进行配置。 消息源需要实现EventSource接口。 该部分实例可以参阅nl.justobjects.pushlet.test.TestEventPushSources类, 这部分内容在后面的 1.2.2 会提到.】

2. 创建接受者。

    正如我们将要看到的那样,pushlet框架为开发senders和receivers提供了多种可能性;由于接口需要通过http(和xml)来访问,所以程序必须支持http协议;

【注:】这里一会message,一会Event,整的人很晕。看过下面对Events介绍再回头看上面一段就会比较清楚

Pushlet Doc 写道
1.1. Events



1.1 事件 【注: 其实就是一个HashMap, 一些key使用了Portocal接口中定义的常量】

Pushlet Doc 写道
The message should adhere to/src/nl/justobjects/pushlet/core/Event.java. Currently Event is a flat message with a topic identifier called thep_subject. Dependent on the client technology different encodings are applied to transfer Event, the main two being JavaScript and XML.
 

   

    The message 需要依附/src/nl/justobjects/pushlet/core/Event.java.类。 当前Event是一个有着"p_subject"标题的一套message. Event的传递依赖客户端的编码技术,主要有Javascript和XML两种方式.

Pushlet Doc 写道
1.2. Developing Senders



1.2. 开发发送者

Pushlet Doc 写道
There are three possibilities to send events to the Pushlet framework: remotely using the Pushlet protocol or locally, using EventSource or directly to the Dispatcher class. Each is discussed next.

 

    可以通过三种方式来想Puhsliet框架发送Events:

1. 远程或者本地使用Pushlet协议,2,3.使用EvenSouce或者直接使用Dipatcher类。下面依次讨论

【注:】所谓协议,其实就是在nl.justobjects.pushlet.core.Protocol接口中定义了一些常量,在开发时需要使用到这些常量。

Pushlet Doc 写道
1.2.1. Direct Publishing (local)

Your application may directly publish Events by using /src/nl/justobjects/pushlet/core/Dispatcher.getInstance().java. Since Dispatcher is (currently) a Singleton, sending the Event is a matter of callingDispatcher.getInstance().multicast()/unicast()/broadcast().

  

    我们的程序可以直接通过/src/nl/justobjects/pushlet/core/Dispatcher.getInstance().java来发布Events. 现在Dispatcher是一个单例,在发送Events时需要通过

Dispatcher.getInstance().multicast() or unicast() or broadcast(). 来进行.


【注:】这里有三个方法,也就是说有 三种形式 :

1. public synchronized void multicast(Event event) : 将当前Event发送给匹配该Event的订阅者(Subscriber)。 在发送时调用subscriber.match(event)来判断当前subscritber是否为匹配当前的Event, 详情可以看Dispatcher的实现;

2. public synchronized void unicast(Event event, String aSessionId) : 将当前Event发送给指定订阅者(Subscriber).

3. public synchronized void broadcast(Event event) : 广播室发送,将当前Event发送给所有订阅者.

Pushlet Doc 写道
The other two methods (EventSource and Pushlet protocol) will eventually call Dispatcher.getInstance().multicast()/unicast()/broadcast().
 

    其他两种发布方式(EventSource[1.2中 中文翻译中提到的 方式2], Pushlet protocal[1.2中 中文翻译提到的 方式1])最终也是通过调用Dispatcher.getInstance().multicast()/unicast()/broadcast() 进行发送的;

Note that in order to call Dispatcher.getInstance().multicast()/unicast()/broadcast(), your class needs to be in the same classloader as the Dispatcher.getInstance(). This may be an issue when for example your sender is in another web application. You may use the Pushlet protocol in that case or put pushlet.jar on the system CLASSPATH. In Tomcat you can also make pushlet.jar a shared library .

Pushlet Doc 写道
1.2.2. Using EventSource

An EventSource is an object that is managed (activated/passivated) by the Pushlet framework. Developing your own EventSource involves creating a class that implements nl.justobjects.pushlet.core.EventSource (when your EventSource pushes Events to the framework) or that extends nl.justobjects.pushlet.core.EventPullSource (when the framework should pull your EventSource at dedicated intervals) and adding your EventSource to a properties file aptly namedsources.properties.

See /webapps/pushlet/WEB-INF/classes/sources.properties for an example. This file specifies which EventSource objects need to be created and managed. Note: since v2.0.3 sources.properties can also be placed under WEB-INF. See /src/nl/justobjects/pushlet/core/EventSourceManager.java how this is done. See examples in /src/nl/justobjects/pushlet/test/TestEventPullSources where several example sources are bundled.

During initialization the EventSourceManager will look for the file sources.properties in the CLASSPATH. Usually this file will be put under WEB-INF/classes.
 

 

    EventSouce是一个被Pushlet框架管理的对象(activated/passivated). 创建一个自己的EventSource有两种方式:

1. 实现nl.justobjects.pushlet.core.EventSource 接口; (when your EventSource pushes Events to the framework)   

2.继承nl.justobjects.pushlet.core.EventPullSource 类,并且将EvenSouce配置到 sources.properties中。 (when the framework should pull your EventSource at dedicated intervals)

【注:】括号里的两句话暂时还没理解是什么意思。大概是:

1. 当EventSouce需要向框架推送Events时, 使用方式1;【暂时还没理解这种方式是做什么用的】

2. 当框架需要不间断的pull your EventSource时, 使用方式2; 【注:这种方式感觉和很像ajax中的轮询,只不是服务器直接向客户端发送,少了一个请求的步骤】

Pushlet Doc 写道
1.2.3. Using the Pushlet protocol

The Chat and WebPresentation examples use the remote publication of events through the Pushlet (control) protocol. In a webapp the Pushlet JS API provides a p_publish() method through which your app may send events.

The /src/nl/justobjects/pushlet/test/PushletPingApplication.java provides a complete example illustrating sending and receiving Events and using/src/nl/justobjects/pushlet/client/PushletClient.java. DHTML clients may use the JavaScript pushlet library.

 为做翻译...

 

Pushlet Doc 写道
1.3. Developing Receivers

1.3.1. The Pushlet Request

Any client that wants to receive Events will make a HTTP request to the Pushlet servlet. This request requires at least two parameters: (1) the encoded Event format format=js|xml|ser|xml-strict where "js" is JavaScript, "xml" is XML, "ser" is Java serialized objects, "xml-strict" is like "xml" but events are contained in a complete document and (2) the subject (like a JMS topic). Note that subjects form a hierarchical tree naming space, i.e. specifying one level will subscribe to all subjects below. If you specify "/" all Events are received.


    任何想要接收Events的客户端都必须先向Pushlet servlet 发送一个HTTP请求,告知服务器要订阅的主题和以什么方式接受数据. 这个请求需要包含至少两个参数:

1. format = js|xml|ser|xml-strict; js->javascript, xml->xml, ser->Java 可序列化对象, xml-strict -> 类似xml但是events报一个完整的document;

2. subject = String 类似于JMS主题。 这里只要传入订阅事件的主题;在Event中该值会被保存到Protocal.P_SUBJECT键中;

要注意的是:主题是一个等级树类型的命名空间。 如果订阅(subscribe)一级主题,则会订阅其下所有子主题。如果指定主题为"/"则订阅所有主题。

【注:】 例如现在又三个主题: "/pushlet/ping", "/pushlet/chat", "/wity/demo";

1. 如果只订阅ping, 则subject="/pushlet/ping"即可;

2. 如果要订阅pushlet下的所有主题, 则subject="/pushlet", 关于"/pushlet/ping","/pushlet/chat"主题的Event都会被接受

3. 当subject="/"时,此时为树根,则订阅所有主题

Pushlet Doc 写道

1.3.2. Using Pull Mode

The Pushlet servlet is the standard servlet used to receive Events. A Pushlet will basically send a stream of encoded Events as specified by the p_format parameter. In some cases (proxies, some servlet engines or browsers) the Pushlet may not be working properly. In that case the pull mode may be used. In pull mode the Pushlet servlet will send one or more Events and request the client to refresh the page. The client refreshes the page each time an event is received, but the request remains outstanding thus pull mode is more efficient than polling. For JavaScript clients it is transparent whether a "stream", "pull" or "poll" mode is active. Other clients (e.g. Java XML-based clients) should merely obey the protocol "refresh" event.

 

Pushlet servlet 是一个用于接受Events的标准Servlet. Pushlet会以p_format参数定义的编码格式发送Events.在一些情况(代理,某些servlet引擎或者浏览器)下,Pushlet可能不能正常的工作。在这种情况下pull mode会被用到。

在pull mode下,Pushlet servlet将会发送一个或者多个Events并且请求客户端刷新页面.客户端刷新一次页面将会受到一个event,但是requeset 仍旧存在(remains outstanding),因此pull mode 比轮询(polling)更高效.

在Javascript客户端中,不论是"stream","pull","poll"模式都是可用的。在其他客户端中(例如:基于xml的java客户端)只能遵循"refresh"协议的event.【注: P_EVENT -> Protocal.E_REFRESH】.

Pushlet Doc 写道
1.3.3. Using DHTML Clients

A DHTML client receives Events encoded as JavaScript callbacks. See most of the examples and the whitepaper how this is done. The simplest example is the temperature display. Seewebapps/pushlet/examples/weather/nl-temperature.html.

The JavaScript library webapps/pushlet/lib/js-pushlet-client.js provides an API that allows your app to access all services of the pushlet protocol. All API methods are named p_*().

 


    在DHTML客户端中使用Javascript callbacks的方式接受Events. 更多关于实现的内容参考白皮书.最简单的例子就是温度显示.详情查看webapps/pushlet/examples/weather/nl-temperature.html. 这个例子.

webapps/pushlet/lib/js-pushlet-client.js库提供了访问pushlet协议的所有方法.所有API方法都以p_开头(即,p_*()的形式).

Pushlet Doc 写道

1.3.4. Using AJAX Clients

Since version 2.0.2 AJAX clients can be developed using the library webapps/pushlet/lib/ajax-pushlet-client.js See for examplewebapps/pushlet/examples/chat. The first version of the AJAX library is forward compatible with webapps/pushlet/lib/js-pushlet-client.js so if you have existing apps you may simply replace this library and remove the p_embed()statement.

TO BE FINALIZED...

 


    从Ajax 客户端2.0.2版开始,可以直接使用 webapps/pushlet/lib/ajax-pushlet-client.js 库进行开发。相关实例可以参考webapps/pushlet/examples/chat 示例。

第一版的Ajax库需要依赖 webapps/pushlet/lib/js-pushlet-client.js 文件,所以如果第一个版的文件还存在你的程序中,只需用新版本的ajax-pushlet-client.js替换掉旧版本,并且一出代码中的p_embed()【注: 这个函数用来在页面嵌入一个iframe】函数即可

 

后面内容未翻译 保留原文...


1.3.5. Using XML Clients

Any client that can receive XML over HTTP can be used. The Java Pushlet client (see/src/nl/justobjects/pushlet/client/PushletClient.java) uses the XML format, decoding incoming XML into Event objects.

If format is "xml" then Events are streamed as <event> elements. If format is "xml-strict" then <event> elements are contained in a <pushlet> element. The latter is applicable for "pull-mode" in AJAX clients (that require to receive a complete XML document).



1.3.6. J2ME Clients

Seeclient/j2me.





1.4. Integrating Pushlets in your WebApp

Although you can develop with Pushlets by using and or modifying the standard web applicationpushlet.war, there may be cases where you want to integrate Pushlets in your own web application. Below are the steps for doing just that. We'll see which files are needed, where to place them and what minor modifications need to be done.

1.4.1. Required Files

Very few files from the standard Pushlet distribution are required to get up and running. These are listed below with their path relative to the top directory of your unpacked distribution i.e. pushlet-x.y.z/webapps/pushlet

jar file: WEB-INF/lib/pushlet.jar

config files: WEB-INF/classes/pushlet.properties and optionally (if you develop event sources) WEB-INF/classes/sources.properties

client libraries: lib/js-pushlet-client.js and lib/js-pushlet-net.html for JavaScript clients. Only if you use applet or WebStart Java clients you 'll need lib/pushletclient.jar

web config file: WEB-INF/web.xml in order to embed the pushlet servlet in your webapp



That's it. You may use (parts of) the examples and assets directories for testing or as a starting point for your application but only the above four categories are required. A bare minimum thus are 5 files (pushlet.jar,pushlet.properties, js-pushlet-client.js, js-pushlet-net.html and web.xml

Note: since v2.0.3 pushlet.properties can also be placed under WEB-INF. At startup the CLASSPATH is searched first followed by WEB-INF/pushlet.properties.



1.4.2. Placing the Files

You need to place the files listed above in exactly the same directories in your webapp. The exception is web.xml as your webapp will also need your ownweb.xml. See next.



1.4.3. Modifications

Assuming your webapp has its own WEB-INF/web.xml you will need to copy/paste the entire Pushlet <servlet> and <servlet-mapping> XML elements from the Pushlet web.xml.

The next step is to decide whether your application is going to use Event sources. If not you won't need sources.properties but you will need to disable Event sources inpushlet.properties. The line to change is

                            sources.activate=true
                       

to                             sources.activate=false
                       



In order to verify test I usually take one of the example files like examples/raw/raw.html to test if connectivity is working.

That's it ! If you integrate Pushlets in your webapp you may next also extend core classes, so read on.





1.5. Advanced: Extending Pushlets

Your application may have specific requirements that may not be covered by the basic Pushlet framework. You may extend core classes (v2.0.3+) of the framework without modifying the core classes. This can be achieved by extending (through inheritance) the main core classes and declaring your extended classes inpushlet.properties. For example, if you need to extend SessionManager for authorization purposes you may declare your com.mine.ExtSessionManager class in pushlet.properties throughsessionmanager.class=com.mine.ExtSessionManager. At runtime the main core classes are created (factory method pattern) using the classes declared inpushlet.properties. Note that you should be maintaining the semantics of the framework. In many cases you can intercept method calls by calling super.method() before/after your specific code. The following classes may be extended:


                    nl.justobjects.pushlet.core.Controller
                    nl.justobjects.pushlet.core.Dispatcher
                    nl.justobjects.pushlet.core.SessionManager
                    nl.justobjects.pushlet.core.Session
                    nl.justobjects.pushlet.core.Subscriber
                    nl.justobjects.pushlet.core.Subscription
                    nl.justobjects.pushlet.util.DefaultLogger
               








Some examples are presented next. First the problem/issue is presented, then a hint at a possible solution through extension.

1.5.1. Caching Events

Problem: when a client subscribes to a subject you may want to send the current state first and then send updates. For example, a table of stock rates need to be filled first before receiving rate changes.

Solution: override the classes Dispatcher and Subscriber. Your Dispatcher.multicast() may store Events in a HashMap keyed by stock name before callingsuper.multicast(). Your Subscriber.addSubscription() may send the content of the HashMap of stock rates to the subscribing client before calling super.addSubscription()

Caching is often application-specific. In other cases, e.g. a chat you may want to cache the last N events using a List.



1.5.2. Notify on Subscribe/Unsubscribe

Problem: Your application needs notification when clients subscribe or unsubscribe to/from subjects.

Solution: override the class Subscriber and override all methods dealing with subscription: Subscriber.add/removeSubscription(s) Call super. first and then publish a custom Event through the Dispatcher.



1.5.3. Only Publish Events When There Are Active Subscribers

Problem: Your application only needs to send events when there are listeners for the topic.

Solution: override the class Subscriber and keep a map of "active topics" by intercepting all Subscriber.add/removeSubscription(s) methods. Then locally or remotely your app may fetch the list (or even a boolean) to determine if the Event needs to be published.



1.5.4. Custom Logging

Problem: You want to use a specific logging library likelog4j.

Solution: override the class nl.justobjects.pushlet.util.DefaultLogger using the property logger.class providing a custom logger class that calls your specific logging library.



1.5.5. Event Throttling

Problem: You don't want to push all events to each subscriber. Some subscribers may have a paid account.

Solution: override the class Subscriber and determine there if a Subscriber needs to receive all events. You may authorize clients by using a custom SessionManager (see above).

2
2
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

Global site tag (gtag.js) - Google Analytics