فهرست منبع

Zend_Feed_Pubsubhubbub: Copy of docs from Incubator for editing

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@19806 44c647ce-9c0f-0410-b52a-842ac1e357ba
padraic 16 سال پیش
والد
کامیت
cedad2b311

+ 81 - 0
documentation/manual/en/module_specs/Zend_Feed_Pubsubhubbub-Introduction.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.feed.pubsubhubbub.introduction">
+    <title>Introduction</title>
+
+    <para>
+        <classname>Zend_Feed_Pubsubhubbub</classname> is an implementation of the PubSubHubbub Core
+        0.2 Specification (Working Draft). It offers implementations of a Pubsubhubbub Publisher and
+        Subscriber suited to Zend Framework and other PHP applications.
+    </para>
+
+    <sect2>
+        <title>What is Pubsubhubbub?</title>
+
+        <para>
+            Pubsubhubbub is an open, simple web-scale pubsub protocol. A common use case to enable
+            blog's (Publishers) to "push" updates from their RSS or Atom feeds (Topics) to end
+            Subscribers. These Subscribers will have subscribed to the blog's RSS or Atom feed via a
+            Hub, a central server which is notified of any updates by the Publisher and which then
+            distributes these updates to all Subscribers. Any feed may advertise that it supports
+            one or more Hubs using an Atom namespaced link element with a rel attribute of "hub".
+        </para>
+
+        <para>
+            Pubsubhubbub has garnered attention because it is a pubsub protocol which is easy to
+            implement, and which operates over HTTP. It's philosophy is to replace the traditional
+            model where blog feeds have been polled at regular intervals to detect and retrieve
+            updates.  Depending on the frequency of polling, this can take a lot of time to
+            propagate updates to interested parties from planet aggregators to desktop readers. With
+            a pubsub system in place, updates are not polled by Subscribers, they are pushed to
+            Subscribers, elimenating any delay. For this reason, Pubsubhubbub forms part of what has
+            been dubbed the real-time web.
+        </para>
+
+        <para>
+            The protocol does not exist in isolation. Pubsub systems have been around for a while,
+            such as the familiar Jabber Publish-Subscribe protocol, XEP-0060, or the less well known
+            rssCloud (described in 2001).  However these have not achieved widespread adoption.
+            rssCloud, which was recently revived with the appearance of Pubsubhubbub, has also seen
+            its usage increase significantly.
+        </para>
+    </sect2>
+
+    <sect2>
+        <title>Zend_Feed_Pubsubhubbub</title>
+
+        <para>
+            <classname>Zend_Feed_Pubsubhubbub</classname> implements two sides of the Pubsubhubbub
+            0.2 Specification: a Publisher and a Subscriber. It does not currently implement a Hub
+            Server.
+        </para>
+
+        <para>
+            A Publisher is responsible for notifying all supported Hubs (many can be supported to
+            add redundancy to the system) of any updates to its feeds, whether they be Atom or RSS
+            based. This is achieved by pinging the supported Hub Servers with the URL of the updated
+            feed. In Pubsubhubbub terminology, any updateable resource capable of being subscribed
+            to is referred to as a Topic. Once a ping is received, the Hub will request the updated
+            feed, process it for updated items, and forward all updates to all Subscribers
+            subscribed to that feed.
+        </para>
+
+        <para>
+            A Subscriber is any party or application which subscribes to one or more Hubs to receive
+            updates from a Topic hosted by a Publisher. The Subscriber never directly communicates
+            with the Publisher, since the Hub acts as an intermediary, accepting subscriptions and
+            sending updates to subscribed Subscribers. The Subscriber therefore communicates only
+            with the Hub, either to subscribe/unsubscribe to Topics, or when it receives updates
+            from the Hub.
+        </para>
+
+        <para>
+            <classname>Zend_Feed_Pubsubhubbub</classname> implements these two sides with the
+            classes <classname>Zend_Feed_Pubsubhubbub_Publisher</classname> and
+            <classname>Zend_Feed_Pubsubhubbub_Subscriber</classname>. In addition, the Subscriber
+            implementation may handle any feed updates from a Hub by using
+            <classname>Zend_Feed_Pubsubhubbub_Subscriber_Callback</classname>.  These are covered in
+            subsequent sections.
+        </para>
+    </sect2>
+</sect1>

+ 85 - 0
documentation/manual/en/module_specs/Zend_Feed_Pubsubhubbub-Pubsubhubbub-Publisher.xml

@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.feed.pubsubhubbub.pubsubhubbub.publisher">
+    <title>Pubsubhubbub Publisher</title>
+
+    <para>
+        In Pubsubhubbub, the Publisher is the party who publishes a live feed and frequently updates
+        it with new content. In order for these updates to be pushed to Subscribers, the Publisher
+        must notify all of its supported Hubs that an update has occured using a simple HTTP POST
+        request containing the URI or the updated Topic (i.e the updated RSS or Atom feed). The Hub
+        will confirm receipt of the notification, fetch the updated feed, and forward any updates to
+        any Subscribers who have subscribed to that Hub for updates from the relevant feed.
+    </para>
+
+    <para>
+        By design, this means the Publisher has very little to do except send these Hub pings
+        whenever its feeds change.
+    </para>
+
+    <sect2 id="zend.feed.pubsubhubbub.pubsubhubbub.publisher.zend.feed.pubsubhubbub.publisher">
+        <title>Zend_Feed_Pubsubhubbub_Publisher</title>
+
+        <para>
+            <classname>Zend_Feed_Pubsubhubbub_Publisher</classname> implements a full Pubsubhubbub
+            Publisher. Its setup for use is also simple, requiring mainly that it is configured with
+            the URI endpoint for all Hubs to be notified of updates, and the URIs of all Topics to
+            be included in the notifications.
+        </para>
+
+        <para>
+            The following example shows a Publisher notifying a collection of Hubs about updates to
+            a pair of local RSS and Atom feeds. The class retains a collection of errors which
+            include the Hub URLs, so the notification can be reattempted later and/or logged if any
+            notifications happen to fail. Each resulting error array also includes a "response" key
+            containing the related HTTP response object.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$publisher = new Zend_Feed_Pubsubhubbub_Publisher;
+$publisher->addHubUrls(array(
+    'http://pubsubhubbub.appspot.com/', 
+    'http://hubbub.example.com',
+));
+$publisher->addUpdatedTopicUrls(array(
+    'http://www.example.net/rss', 
+    'http://www.example.net/atom',
+));
+$publisher->notifyAll();
+
+if (!$publisher->isSuccess()) {
+    // check for errors
+    $errors     = $publisher->getErrors();
+    $failedHubs = array()
+    foreach ($errors as $error) {
+        $failedHubs[] = $error['hubUrl'];
+    }
+}
+
+// reschedule notifications for the failed Hubs
+]]></programlisting>
+
+        <para>
+            If you prefer having more concrete control over the Publisher, the methods
+            <methodname>addHubUrls()</methodname> and <methodname>addUpdatedTopicUrls()</methodname>
+            pass each array value to the singular <methodname>addHubUrl()</methodname> and
+            <methodname>addUpdatedTopicUrl()</methodname> public methods.  There are also matching
+            <methodname>removeUpdatedTopicUrl()</methodname> and
+            <methodname>removeHubUrl()</methodname> methods.
+        </para>
+
+        <para>
+            You can also skip setting Hub URIs, and notify each in turn using the
+            <methodname>notifyHub()</methodname> method which accepts the URI of a Hub endpoint as
+            its only argumement.
+        </para>
+
+        <para>
+            There are no other tasks to cover. The Publisher implementation is very simple since
+            most of the feed processing and distribution is handled by the selected Hubs. It is
+            however important to detect errors and reschedule notifications as soon as possible
+            (with a reasonable maximum number of retries) to ensure notifications reach all
+            Subscribers.
+        </para>
+    </sect2>
+</sect1>

+ 318 - 0
documentation/manual/en/module_specs/Zend_Feed_Pubsubhubbub-Pubsubhubbub-Subscriber.xml

@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.feed.pubsubhubbub.pubsubhubbub.subscriber">
+    <title>Pubsubhubbub Subscriber</title>
+
+    <para>
+        In Pubsubhubbub, the Subscriber is the party who wishes to receive updates to any Topic (RSS
+        or Atom feed). They achieve this by subscribing to one or more of the Hubs advertised by
+        that Topic, usually as a set of one or more atom links with a rel attribute of "hub". The
+        Hub from that point forward will send an Atom or RSS feed containing all updates to that
+        Subscriber's Callback URL when it receives an update notification from the Publisher. In
+        this way, the Subscriber need never actually visit the original feed (though it's still
+        recommended at some level to ensure updates are retrieved if ever a Hub goes offline). All
+        subscription requests must contain the URI of the Topic being subscribed and a Callback URL
+        which that the Hub will use to confirm the subscription and to forward updates.
+    </para>
+
+    <para>
+        The Subsciber therefore has two roles. To create and manage subscriptions, including
+        subscribing for new Topics with a Hub, unsubscribing (if necessary), and periodically
+        renewing subscriptions since they have a limited validity as set by the Hub. This is handled
+        by <classname>Zend_Feed_Pubsubhubbub_Subscriber</classname>.
+    </para>
+
+    <para>
+        The second role, is to accept updates sent by a Hub to the Subscriber's Callback URL, i.e.
+        the URI the Subscriber has assigned to handle updates. The Callback URL also handles events
+        where the Hub contacts the Subscriber to confirm all subscriptions and unsubscriptions.
+        This is handled by using an instance of
+        <classname>Zend_Feed_Pubsubhubbub_Subscriber_Callback</classname> when the Callback URL is
+        accessed.
+    </para>
+
+    <important>
+        <para>
+            <classname>Zend_Feed_Pubsubhubbub_Subscriber</classname> implements the Pubsubhubbub 0.2
+            Specification. As this is a new specification version not all Hubs currently implement
+            it. The new specification allows the Callback URL to include a query string which is
+            used by this class, but not supported by all Hubs. Unfortunately, the previous
+            specification was difficult to use within an application using Routing, i.e. many
+            application frameworks, so this component does NOT support 0.1 Hubs.
+        </para>
+    </important>
+
+    <sect2 id="zend.feed.pubsubhubbub.pubsubhubbub.subscriber.subscribing.and.unsubscribing">
+        <title>Subscribing and Unsubscribing</title>
+
+        <para>
+            <classname>Zend_Feed_Pubsubhubbub_Subscriber</classname> implements a full Pubsubhubbub
+            Subscriber capable of subscribing to, or unsubscribing from, any Topic via any Hub
+            advertised by that Topic.  It operates in conjunction with
+            <classname>Zend_Feed_Pubsubhubbub_Subscriber_Callback</classname> which accepts requests
+            from a Hub to confirm all subscription or unsubscription attempts (to prevent
+            third-party misuse).
+        </para>
+
+        <para>
+            Any subscription (or unsubscription) requires the relevant information before
+            proceeding, i.e. the URI of the Topic (Atom or RSS feed) to be subscribed to for
+            updates, and the URI of the endpoint for the Hub which will handle the subscription and
+            forwarding of the updates. It should also be noted that subscriptions have a default
+            life of 30 days, changeable by the Hub, meaning that subscriptions must be renewed
+            periodically before they expire - simply attempt to re-subsribe before the expiry date
+            of the original subscription. This component does not handle automated subscription
+            renewals.
+        </para>
+
+        <para>
+            With the relevant information to hand, a subscription can be attempted:
+        </para>
+
+        <programlisting lang="php"><![CDATA[
+$storage = new Zend_Feed_Pubsubhubbub_Storage_Filesystem;
+$storage->setDirectory('../tmp');
+
+$subscriber = new Zend_Feed_Pubsubhubbub_Subscriber;
+$subscriber->setStorage($storage);
+$subscriber->addHubUrl('http://hubbub.example.com');
+$subscriber->setTopicUrl('http://www.example.net/rss.xml');
+$subscriber->setCallbackUrl('http://www.mydomain.com/hubbub/callback');
+$subscriber->subscribeAll();
+]]></programlisting>
+
+        <para>
+            Behind the scenes, the Subscriber will send a request to the Hub endpoint containing the
+            following parameters (based on the previous example):
+        </para>
+
+        <table id="zend.feed.pubsubhubbub.pubsubhubbub.subscriber.subscribing.and.unsubscribing.table">
+            <title>Subscription request parameters</title>
+
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Parameter</entry>
+
+                        <entry>Value</entry>
+
+                        <entry>Explanation</entry>
+                    </row>
+                </thead>
+
+                <tbody>
+                    <row>
+                        <entry>hub.callback</entry>
+
+                        <entry>http://www.mydomain.com/hubbub/callback?xhub.subscription=5536df06b5dcb966edab3a4c4d56213c16a8184</entry>
+
+                        <entry>
+                            <para>
+                                The URI used by a Hub to contact the Subscriber and either request
+                                confirmation of a (un)subscription request or send updates from
+                                subscribed feeds. The appended query string contains a custom
+                                parameter (hence the xhub designation). It is a query string
+                                parameter preserved by the Hub and resent with all Subscriber
+                                requests. Its purpose is to allow the Subscriber to identify and
+                                look up the subscription associated with any Hub request in a
+                                backend storage medium.  This is a non-standard parameter used by
+                                this component in preference to encoding a subscription key in the
+                                URI path which is more difficult to implement in a Zend Framework
+                                application.
+                            </para>
+                        </entry>
+                    </row>
+
+                    <row>
+                        <entry>hub.lease_seconds</entry>
+
+                        <entry>2592000</entry>
+
+                        <entry>
+                            <para>
+                                The number of seconds for which the Subscriber would like a new
+                                subscription to remain valid for. Hubs may enforce their own maximum
+                                subscription period. All subscriptions must be renewed by simply
+                                re-subscribing before the subscription period ends to ensure
+                                continuity of updates.
+                            </para>
+                        </entry>
+                    </row>
+
+                    <row>
+                        <entry>hub.mode</entry>
+
+                        <entry>subscribe</entry>
+
+                        <entry>
+                            <para>
+                                Simple value indicating this is a subscription request.
+                                Unsubscription requests would use the "unsubscribe" value.
+                            </para>
+                        </entry>
+                    </row>
+
+                    <row>
+                        <entry>hub.topic</entry>
+
+                        <entry>http://www.example.net/rss.xml</entry>
+
+                        <entry>
+                            <para>
+                                The URI of the topic (i.e. Atom or RSS feed) which the Subscriber
+                                wishes to subscribe to for updates.
+                            </para>
+                        </entry>
+                    </row>
+
+                    <row>
+                        <entry>hub.verify</entry>
+
+                        <entry>sync</entry>
+
+                        <entry>
+                            <para>
+                                Indicates to the Hub the preferred mode of verifying subscriptions
+                                or unsubscriptions. It is repeated twice in order of preference.
+                            </para>
+                        </entry>
+                    </row>
+
+                    <row>
+                        <entry>hub.verify</entry>
+
+                        <entry>async</entry>
+
+                        <entry>
+                            <para>
+                                Indicates to the Hub the preferred mode of verifying subscriptions
+                                or unsubscriptions. It is repeated twice in order of preference.
+                            </para>
+                        </entry>
+                    </row>
+
+                    <row>
+                        <entry>hub.verify_token</entry>
+
+                        <entry>3065919804abcaa7212ae89.879827871253878386</entry>
+
+                        <entry>
+                            <para>
+                                A verification token returned to the Subscriber by the Hub when it
+                                is confirming a subscription or unsubscription. Offers a measure of
+                                reliance that the confirmation request originates from the correct
+                                Hub to prevent misuse.
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            You can modify several of these parameters to indicate a different preference.  For
+            example, you can set a different lease seconds value using
+            <methodname>Zend_Pubsubhubbub_Subscriber::setLeaseSeconds()</methodname> or show a
+            preference for the async verify mode by using <code>
+                setPreferredVerificationMode(Zend_Feed_Pubsubhubbub::VERIFICATION_MODE_ASYNC)</code>.
+        </para>
+
+        <note>
+            <para>
+                While Hubs may require the use of a specific verification mode (both are supported
+                by <classname>Zend_Pubsubhubbub</classname>), you may indicate a specific preference
+                using the <methodname>setPreferredVerificationMode()</methodname> method. In "sync"
+                (synchronous) mode, the Hub attempts to confirm a subscription as soon as it is
+                received, and before responding to the subscription request. In "async"
+                (asynchronous) mode, the Hub will return a response to the subscription request
+                immediately, and its verification request may occur at a later time. Since
+                <classname>Zend_Pubsubhubbub</classname> implements the Subscriber verification role
+                as a separate callback class and requires the use of a backend storage medium, it
+                actually supports both transparently.
+            </para>
+        </note>
+
+        <para>
+            Unsubscribing from a Topic follows the exact same pattern as the previous example, with
+            the exception that we should call <methodname>unsubscribeAll()</methodname> instead. The
+            parameters included are identical to a subscription request with the exception that
+            "hub.mode" is set to "unsubscribe".
+        </para>
+
+        <para>
+            By default, a new instance of <classname>Zend_Pubsubhubbub_Subscriber</classname> will
+            attempt to use a file backed storage medium which defaults to the location of your
+            system's temporary directory. It is recommended to set a custom storage solution where
+            possible. At present the available storage solutions include
+            <classname>Zend_Pubsubhubbub_Storage_Filesystem</classname> and
+            <classname>Zend_Pubsubhubbub_Storage_Memory</classname>. You may set a storage object
+            using <methodname>setStorage()</methodname>.  All storage objects must implement the
+            interface <classname>Zend_Feed_Pubsubhubbub_StorageInterface</classname>.
+            <emphasis>TODO</emphasis>
+        </para>
+    </sect2>
+
+    <sect2 id="zend.feed.pubsubhubbub.pubsubhubbub.subscriber.handling.hub.callbacks">
+        <title>Handling Subscriber Callbacks</title>
+
+        <para>
+            Whenever a subscription or unsubscription request is made, the Hub must verify the
+            request by forwarding a new verification request to the Callback URL set in the
+            subscription/unsubscription parameters. To handle these Hub requests, which will include
+            all future communications contain Topic updates, the Callback URL should trigger the
+            execution of an instance of <classname>Zend_Pubsubhubbub_Subscriber_Callback</classname>
+            to handle the request.
+        </para>
+
+        <para>
+            The Callback class should be configured to use the same storage medium as the Subscriber
+            class. Using it is quite simple since most of its work is performed internally.
+        </para>
+
+        <programlisting lang="php"><![CDATA[
+$storage = new Zend_Feed_Pubsubhubbub_Storage_Filesystem;
+$storage->setDirectory('../tmp');
+
+$callback = new Zend_Feed_Pubsubhubbub_Subscriber_Callback;
+$callback->setStorage($storage);
+$callback->handle();
+$callback->sendResponse();
+
+/**
+ * Check if the callback resulting in the receipt of a feed update.
+ * Otherwise it was either a (un)sub verification request or invalid request.
+ */
+if ($callback->hasFeedUpdate()) {
+    $feedString = $callback->getFeedUpdate();
+    /**
+     *  Process the feed update asynchronously to avoid a Hub timeout
+     */
+}
+]]></programlisting>
+
+        <note>
+            <para>
+                It should be noted that
+                <classname>Zend_Feed_Pubsubhubbub_Subscriber_Callback</classname> independently
+                parses any incoming query string and other parameters.  This is necessary since PHP
+                alters the structure and keys of a query string when it is parsed into the
+                <varname>$_GET</varname> or <varname>$_POST</varname> superglobals.  For example,
+                all duplicate keys are ignored and periods are converted to underscores.
+                Pubsubhubbub features both of these in the query strings it generates.
+            </para>
+        </note>
+
+        <important>
+            <para>
+                It is essential that developers recognise that Hubs are only concerned with sending
+                requests and receiving a response which verifies its receipt. If a feed update is
+                received, it should never be processed on the spot since this leaves the Hub waiting
+                for a response. Rather, any processing should be offloaded to another process or
+                deferred until after a response has been returned to the Hub. One symptom of a
+                failure to promptly complete Hub requests is that Hub may continue to attempt
+                delivery of the update/verification request leading to duplicated update attempts
+                being processed by the Subscriber.
+            </para>
+        </important>
+    </sect2>
+</sect1>