Gallery: 嵌入:基于事件的松耦合整合:修订间差异

来自站长百科
跳转至: 导航、​ 搜索
无编辑摘要
第1行: 第1行:
= Event-Based Loose-Coupled Integration =
= 基于事件的松耦合整合 =
This documents describes loose-coupled integration based on event-driven synchronization, its implementation, the alternatives and how standards could improve interoperability between applications for the whole web application community.
该文档描述说明基于事件驱动同步的松耦合整合,其实现和备选方法,以及这些标准如何能够提高整个web应用程序群中应用程序的互通性的。


Please take a look at the overview of [[Gallery:Embedding|Gallery 2 Embedding]].
请参阅有关[[Gallery:Embedding|Gallery2嵌入]]的综述。


== What is Event-Based Loose-Coupled Integration ==
== 什么是基于事件的松耦合整合 ==
Event-based loose-coupled integration is a '''method to integrate or embed one web application in another''', e.g. to integrate a photo album application in a content management system, or to merge a blog with a forum.
基于事件的松耦合整合是'''将某个web应用程序整合或嵌入另一应用程序中的方法''',如,将某个相片相册程序整合到某个内容管理系统中,或将某个blog与某个论坛进行合并。


The two terms '''loose-coupled''' and '''event-based''' can be explained separately, but only the combination of the two provides a complete solution for integrating / merging two or more web applications.
其中的两个术语'''松耦合(loose-coupled)''''''基于事件(event-based)'''可以分开解释;但只有将两者结合起来才能够理解应用程序整合/合并的完整方法。


=== Loose-Coupled Integration ===
=== 松耦合整合 ===
Loose-coupled means that '''the two applications are unchanged and each application exposes an interface through which it should be accessed by other applications'''. The two applications do not depend on each other, but they can delegate responsibilities like login / authentication to another application by communicating through the interfaces.
松耦合的意思就是'''两个应用程序不被改变,而各应用程序都暴露一个接口,而两应用程序间能通过此接口互访。'''。两个应用程序不依赖对方,但它们通过这些接口进行交流以承担相互间登入/验证的职责。


Integrating application A into another application B is done by having some glue code on top / as a plugin of B which calls A to get the generated output (HTML) and then B puts the generated output in its own output and returns the whole output to the user.
整合应用程序A至B中,通过顶部的一些胶水代码(glue code)/作为B的插件,呼叫A获取生成的输出(HTML),接着B将这些生成的输出置入自己的输出并将整个输出返回给用户。
   User  -- request --> Application B (e.g. a CMS)
   用户 – 请求--> 应用程序B(如一个CMS)
                         |____ B initializes etc.
                         |____ B初始化。
                         |____ B authenticates the
                         |____ B认证
                         |    active user
                         |    活动用户
                         |____ If the request is for -- B calls --> Application A (e.g. a forum)
                         |____ 如请求针对 -- B呼叫--> 应用程序A(如一个论坛)
                         |    an integrated page of                   |____ A handles the request
                         |    B中某A的                   |____ A 处理该请求
                         |    of A in B                                     and returns the output
                         |    整合页面                                     并返回输出
                         |                            <- A returns -
                         |                            <- A 返回 -
                         |     
                         |     
                         |____ B assembles the whole
                         |____ B组合整个
                         |    page output and embeds
                         |    页面输出并将
                         |    A's output in it
                         |    A的输出嵌入其中
                         |____ B returns the requested
                         |____ B向用户返回
                         |    page to the user
                         |    被请求的页面
   User  <-- output ---  |
   用户 <-- 输出---  |


Application A relies on application B supplying enough information in its call to application A. Most importantely information about the authenticated user. For web applications, it's also important that B tells A how the URLs are supposed to look like that it should generate.
应用程序A依靠应用程序B在其对A的呼叫中提供足够的信息。最重要的是有关经认证用户的信息。对于web应用程序来说,B告知A 所生成URL的表现方式也同样重要。


But its important to note that A and B just communicate with each other through a clearly defined interface or protocol and they don't access each others data structures or functions directly.
还有就是注意A和B通过各自经清晰定义的接口或协议互访,而他们不会直接对各自的数据结构或函数进行访问。


TODO: Say something about:
备忘:请介绍些有关:
interfaces, API, protocols, master-slave relationship
接口,API,协议及主仆关系的信息。


=== Event-Based Synchronization ===
=== 基于事件的同步 ===
Since the applications are loose-coupled and don't share the same data, they need to notify each other of changes or generally events that could affect the other application. Such events include:
由于应用程序是松耦合并且不共享数据的,它们就需要告知彼此相关的变更或足以影响彼此的事件。这些事件包括:
* Creation of a new user
* 新用户的创建
* Update of some user data like the email address
* 某些用户数据的更新,如电子邮件地址
* Deletion of a user
* 某个用户的删除
* Login, Logout
* 登入,登出
* Application settings
* 应用程序设定
* ...
* ...
So each time a new user gets created in one application, it notifies the other application through the well-defined interface of this event along with the user name, user data etc. Then the other application can take an appropriate action which is in this case the creation of a corresponding user and to map the two users by their name or id number.
因此每当新用户在某个应用程序中被创建时,它都会通过该事件经定义的接口告知另一个应用程序相关的用户名,用户数据等。接着后者就会做出适当的反应,在此例中就是创建一个对应的用户并按用户名或id编号使两者进行映射。


TODO: Say something about:
备忘:请介绍些有关:
hooks, events
hook和事件的信息。


=== Summary ===
=== 摘要 ===
Loose-coupled integration together with event-based notification ensure that the two applications:
松耦合整合加上基于事件的通告将保证两应用程序:
* can be developed independently and don't need to be forked / hacked
* 可独立开发而无需forked / hacked
* never get out of sync'
* 永不会失去同步
* are easy to integrate
* 易于整合


Usually the integrations are one-sided, that is, as in this example A is embedded in B. B is the master, A is the slave and the communication / notification in this master-slave relationship is only simplex. B notifies A of changes, requests data from A, but it's never the other way around.
通常整合都是单方的,正如例子中所见,A被嵌入到B中。B是主,A就是仆。此主仆关系中的交流/通知仅为simplex的。B通知A有关的变更,向A请求数据,并且这种方式永远不会倒过来。


== Why Loose-Coupled? ==
== 为何要松耦合? ==
The alternative to a loose-coupled system is a '''tight integration''' where data structures (database tables, ...) and / or function calls of the two applications are interweaved to a point where it becomes unmaintainable, there are more and more cross-dependencies all over and the resulting system is (almost) a fork of the two other applications.
The alternative to a loose-coupled system is a '''tight integration''' where data structures (database tables, ...) and / or function calls of the two applications are interweaved to a point where it becomes unmaintainable, there are more and more cross-dependencies all over and the resulting system is (almost) a fork of the two other applications.


第68行: 第68行:
The main goal of '''loose-coupled''' integration is to provide a very well integrated experience for the end-user while keeping the involved applications as separate as possible in the back-end. Well defined interfaces and a good design guarantee that there are no drawbacks for the end-user compared to tight integrations.
The main goal of '''loose-coupled''' integration is to provide a very well integrated experience for the end-user while keeping the involved applications as separate as possible in the back-end. Well defined interfaces and a good design guarantee that there are no drawbacks for the end-user compared to tight integrations.


== Why Event-Based? ==
== 为何要基于事件? ==
The alternative to event-based notifications of changes is '''on-the-fly notifications''' that is, instead of notifying the other applications exactly when the event happens, the other application is notified on-the-fly when a user requests the next embedded page.
The alternative to event-based notifications of changes is '''on-the-fly notifications''' that is, instead of notifying the other applications exactly when the event happens, the other application is notified on-the-fly when a user requests the next embedded page.


第85行: 第85行:
Therefore we classify on-the-fly synchronization as a '''low-tech fallback solution''' for applications that are not ready to provide events / hooks such that plugins or other applications can hook into core functionality like the user creation.
Therefore we classify on-the-fly synchronization as a '''low-tech fallback solution''' for applications that are not ready to provide events / hooks such that plugins or other applications can hook into core functionality like the user creation.


== Implementation ==
== 实现 ==
In this example we use the same pattern of a master-slave relationship as the one used before.
In this example we use the same pattern of a master-slave relationship as the one used before.


=== Master Application ===
=== 主应用程序 ===
The master application is the principle application receiving and handling requests by users and serving the resulting pages. A typical example is a content management system.
The master application is the principle application receiving and handling requests by users and serving the resulting pages. A typical example is a content management system.


Let's further assume the master application is modular and developers can extend its functionality with plugins (or modules, extensions, componennts, ...). To embed a slave application, e.g. a forum or a photo management system, in the master application, you would then write a new plugin for the master. The plugin consists of a small wrapper scripts which communicates with the slave.  
Let's further assume the master application is modular and developers can extend its functionality with plugins (or modules, extensions, componennts, ...). To embed a slave application, e.g. a forum or a photo management system, in the master application, you would then write a new plugin for the master. The plugin consists of a small wrapper scripts which communicates with the slave.  


==== Wrapper Script ====
==== 封包脚本 ====
Sample for the wrapper script:
Sample for the wrapper script:
   $userId = getUserId(); // get the userId of the current active user in the master application
   $userId = getUserId(); // get the userId of the current active user in the master application
第103行: 第103行:
Then the master would embed the generated $html in one of its own templates and return the complete rendered page to the user.
Then the master would embed the generated $html in one of its own templates and return the complete rendered page to the user.


==== Event Synchronization ====
==== 事件同步 ====
We also assume the master application has a built-in event or hook system that enables its plugins to execute their own code on events such as user creation, login or configuration changes. An illutrative implementation of an event system could look like this (we don't encourage the use of globals, but they are illustrative):
We also assume the master application has a built-in event or hook system that enables its plugins to execute their own code on events such as user creation, login or configuration changes. An illutrative implementation of an event system could look like this (we don't encourage the use of globals, but they are illustrative):
   function create_user($username, $password) {
   function create_user($username, $password) {
第129行: 第129行:
Of course you wouldn't implement an event / hooking system that way, but the important part is that there is an event when a user is created in the master application and that plugins of the master application can register themselves as an event listener or hook somehow into core functionality such that they can execute their embed_create_user() function when a user is created.
Of course you wouldn't implement an event / hooking system that way, but the important part is that there is an event when a user is created in the master application and that plugins of the master application can register themselves as an event listener or hook somehow into core functionality such that they can execute their embed_create_user() function when a user is created.


=== Slave Application ===
=== 仆应用程序 ===
The primary task of the slave application is to offer an interface or a protocol of integration related methods. This interface must offer methods to:
The primary task of the slave application is to offer an interface or a protocol of integration related methods. This interface must offer methods to:
* Initialize the application (as an alternative to the normal index.php entry point)
* Initialize the application (as an alternative to the normal index.php entry point)
第153行: 第153行:




== Standardization ==
== 标准化 ==
Integrating a web application into another can be quite complicating since only a small percentage is designed to also work when embedded and only a few frameworks / applications are designed to offer the means to embed other applications into them.
Integrating a web application into another can be quite complicating since only a small percentage is designed to also work when embedded and only a few frameworks / applications are designed to offer the means to embed other applications into them.


第174行: 第174行:
CMS devs usually want to develop their own solution, favor their own forum or gallery solution etc since they believe that one day, they'll have all the features needed, plus it's then an integral part of their CMS, well desgined and their code is better anyway :) Of course we have to accept and appreciate this position, but with integration/interoperability standards, applications could achieve the same, without having to develop specialized solutions like a forum system.
CMS devs usually want to develop their own solution, favor their own forum or gallery solution etc since they believe that one day, they'll have all the features needed, plus it's then an integral part of their CMS, well desgined and their code is better anyway :) Of course we have to accept and appreciate this position, but with integration/interoperability standards, applications could achieve the same, without having to develop specialized solutions like a forum system.


== Applications Supporting Event-Based Integration ==  
== 支持基于事件整合的应用程序 ==  
As a master application:
As a master application:
* Gallery2 (90% events / hooks for user / group create / update / delete, logout, login, ..missing: configuration changes)
* Gallery2 (90% events / hooks for user / group create / update / delete, logout, login, ..missing: configuration changes)
第190行: 第190行:
* Pretty all scripts, since you can always add a layer / interface which calls the internal functions and add output buffering around it. But they need to provide basic means to dictate the URL format etc.
* Pretty all scripts, since you can always add a layer / interface which calls the internal functions and add output buffering around it. But they need to provide basic means to dictate the URL format etc.


== References ==  
== 参考 ==  
Event-based loose integration is an obvious and the most prominent approach to software integration for a long time now. These are a few papers and references on the topic:
Event-based loose integration is an obvious and the most prominent approach to software integration for a long time now. These are a few papers and references on the topic:
* Daniel J. Barrett, Lori A. Clarke, Peri L. Tarr, Alexander E. Wise, [ftp://ftp.cs.umass.edu/pub/techrept/techreport/1996/UM-CS-1996-068.ps "A Framework for Event-Based Software Integration"] (Postscript, 461K). ACM Transactions on Software Engineering and Methodology (TOSEM), Volume 5 Number 4, October 1996. Also see: http://www.blazemonger.com/publications.html#ACADEMIC
* Daniel J. Barrett, Lori A. Clarke, Peri L. Tarr, Alexander E. Wise, [ftp://ftp.cs.umass.edu/pub/techrept/techreport/1996/UM-CS-1996-068.ps "A Framework for Event-Based Software Integration"] (Postscript, 461K). ACM Transactions on Software Engineering and Methodology (TOSEM), Volume 5 Number 4, October 1996. Also see: http://www.blazemonger.com/publications.html#ACADEMIC

2008年10月20日 (一) 13:34的版本

基于事件的松耦合整合

该文档描述说明基于事件驱动同步的松耦合整合,其实现和备选方法,以及这些标准如何能够提高整个web应用程序群中应用程序的互通性的。

请参阅有关Gallery2嵌入的综述。

什么是基于事件的松耦合整合

基于事件的松耦合整合是将某个web应用程序整合或嵌入另一应用程序中的方法,如,将某个相片相册程序整合到某个内容管理系统中,或将某个blog与某个论坛进行合并。

其中的两个术语松耦合(loose-coupled)基于事件(event-based)可以分开解释;但只有将两者结合起来才能够理解应用程序整合/合并的完整方法。

松耦合整合

松耦合的意思就是两个应用程序不被改变,而各应用程序都暴露一个接口,而两应用程序间能通过此接口互访。。两个应用程序不依赖对方,但它们通过这些接口进行交流以承担相互间登入/验证的职责。

整合应用程序A至B中,通过顶部的一些胶水代码(glue code)/作为B的插件,呼叫A获取生成的输出(HTML),接着B将这些生成的输出置入自己的输出并将整个输出返回给用户。

 用户 – 请求--> 应用程序B(如一个CMS)
                        |____ B初始化。
                        |____ B认证 
                        |     活动用户
                        |____ 如请求针对  -- B呼叫--> 应用程序A(如一个论坛)
                        |     B中某A的                   |____ A 处理该请求 
                        |     整合页面                                     并返回输出
                        |                            <- A 返回 -
                        |     
                        |____ B组合整个 
                        |     页面输出并将
                        |     A的输出嵌入其中
                        |____ B向用户返回 
                        |     被请求的页面
 用户 <-- 输出---   |

应用程序A依靠应用程序B在其对A的呼叫中提供足够的信息。最重要的是有关经认证用户的信息。对于web应用程序来说,B告知A 所生成URL的表现方式也同样重要。

还有就是注意A和B通过各自经清晰定义的接口或协议互访,而他们不会直接对各自的数据结构或函数进行访问。

备忘:请介绍些有关: 接口,API,协议及主仆关系的信息。

基于事件的同步

由于应用程序是松耦合并且不共享数据的,它们就需要告知彼此相关的变更或足以影响彼此的事件。这些事件包括:

  • 新用户的创建
  • 某些用户数据的更新,如电子邮件地址
  • 某个用户的删除
  • 登入,登出
  • 应用程序设定
  • ...

因此每当新用户在某个应用程序中被创建时,它都会通过该事件经定义的接口告知另一个应用程序相关的用户名,用户数据等。接着后者就会做出适当的反应,在此例中就是创建一个对应的用户并按用户名或id编号使两者进行映射。

备忘:请介绍些有关: hook和事件的信息。

摘要

松耦合整合加上基于事件的通告将保证两应用程序:

  • 可独立开发而无需forked / hacked
  • 永不会失去同步
  • 易于整合

通常整合都是单方的,正如例子中所见,A被嵌入到B中。B是主,A就是仆。此主仆关系中的交流/通知仅为simplex的。B通知A有关的变更,向A请求数据,并且这种方式永远不会倒过来。

为何要松耦合?

The alternative to a loose-coupled system is a tight integration where data structures (database tables, ...) and / or function calls of the two applications are interweaved to a point where it becomes unmaintainable, there are more and more cross-dependencies all over and the resulting system is (almost) a fork of the two other applications.

What happens if one of the applications has a new release? The authors of the integration would then have to backport all the changes to their forked integration system. Or apply all the hacks to the new release.

This is not a fictional scenario, there are plenty of examples of such integrations, e.g. PNphpBB (PostNuke fork of phpBB).

Such tight integrations are not easy to maintain and require a dedicated team to keep it up to date and to port security patches and fixes from the original applications to the fork / hacked integration. Depending on a third, often very small and not well-organized team of developers for a production-level application is sure not preferable. Developers lose their interest and it's important to have applications backed by large development teams guaranteeing continued support and development. Also, being able to quickly apply critical security patches is also of great importance.

The main goal of loose-coupled integration is to provide a very well integrated experience for the end-user while keeping the involved applications as separate as possible in the back-end. Well defined interfaces and a good design guarantee that there are no drawbacks for the end-user compared to tight integrations.

为何要基于事件?

The alternative to event-based notifications of changes is on-the-fly notifications that is, instead of notifying the other applications exactly when the event happens, the other application is notified on-the-fly when a user requests the next embedded page.

Example:

  1. A new user is created in application B (e.g. a CMS)
  2. The same user visits an embedded page of A in B
  3. When A is called by B, A checks whether the user already exists in A, if not, the user is created.
  4. A handles the request in any case and returns the data as usual

In this case we talk of on-the-fly user creation.

The problems of on-the-fly user creation are obvious:

  • As long as a user doesn't visit an embedded page of A in B, the changes are not synchronized. If A has features like mass-emails to all registered users, it won't send emails to all registered users since only a subset already have an account in A
  • Only a small subclass of changes can be synchronized on-the-fly. User deletion, user data changes (e.g. email address), logout, configuration changes, ... cannot be synchronized without a performance penalty using a workaround like checking for a list of queued changes on each embedded request or trade-off solutions like running a synchronization task periodically

Therefore we classify on-the-fly synchronization as a low-tech fallback solution for applications that are not ready to provide events / hooks such that plugins or other applications can hook into core functionality like the user creation.

实现

In this example we use the same pattern of a master-slave relationship as the one used before.

主应用程序

The master application is the principle application receiving and handling requests by users and serving the resulting pages. A typical example is a content management system.

Let's further assume the master application is modular and developers can extend its functionality with plugins (or modules, extensions, componennts, ...). To embed a slave application, e.g. a forum or a photo management system, in the master application, you would then write a new plugin for the master. The plugin consists of a small wrapper scripts which communicates with the slave.

封包脚本

Sample for the wrapper script:

 $userId = getUserId(); // get the userId of the current active user in the master application
 $baseUrl = getBaseUrl(); // get the base URL of all URLs that point to the master application
 include('some/path/to/slaveApplication/embed.php'); // include the interface exposed by the slave application
 embed_init($userId, $baseUrl); // initialize the slave application with the authenticated user and the base URL
 $html = embed_run(); // let the slave application handle the current request and return the resulting HTML

Then the master would embed the generated $html in one of its own templates and return the complete rendered page to the user.

事件同步

We also assume the master application has a built-in event or hook system that enables its plugins to execute their own code on events such as user creation, login or configuration changes. An illutrative implementation of an event system could look like this (we don't encourage the use of globals, but they are illustrative):

 function create_user($username, $password) {
     ... // create the user as usual
     global $hooks;
     if (!empty($hooks[CREATE_USER])) { // check if there are any registered event listeners / hooks
         foreach ($hooks[CREATE_USER] as $event_handler) {
             $event_handler->handle_event($username, $password);
         }
     }
 }

A plugin of the master application could register an event handler like this:

 $GLOBALS['hooks'][CREATE_USER][] = new my_create_user_handler();

And the handler itself would look like this:

 class my_create_user_handler {
     function handle_event($username, $password) {
         // synchronize user creation to our embedded application
         include('path/to/slaveApplication/embed.php'); // include the interface to the slave application
         embed_init(); // initialize the slave application
         embed_create_user($username, $password); // create the user in the embedded application
     }
 }

Of course you wouldn't implement an event / hooking system that way, but the important part is that there is an event when a user is created in the master application and that plugins of the master application can register themselves as an event listener or hook somehow into core functionality such that they can execute their embed_create_user() function when a user is created.

仆应用程序

The primary task of the slave application is to offer an interface or a protocol of integration related methods. This interface must offer methods to:

  • Initialize the application (as an alternative to the normal index.php entry point)
  • Create / update / delete users
  • login / logout users
  • ...

A sample interface could look like this (the embed.php file referenced above):

 function embed_init($userId=null, $baseUrl=null) {
     include(..); // include some files, intitialize the application
     $user = get_user_by_mapped_external_userid($userId);
     set_active_user($user);
 }
 function embed_run() {
     $mode = 'embedded';
     $html = main($mode); // call the application in embedded mode (return html instead of printing to browser, ...)
     return $html;
 }
 function embed_create_user($username, $password) {
     some_api_call_to_create_user($username, $password);
 }

The slave application must of course meet a lot of requirements that allow it to run in embedded mode. But the important bit here is that the inner architecture of the application is hidden and only a stable, simple interface is exposed to the master application.


标准化

Integrating a web application into another can be quite complicating since only a small percentage is designed to also work when embedded and only a few frameworks / applications are designed to offer the means to embed other applications into them.

If there was a standardized way of integrating applications with specifications that must be met by the master and by the slave applications, writing an integration could be faciliated a lot. Everyone would profit:

  • There would be clear, standardized patterns and specifications to follow when designing an application for integration
  • Interoperability of a large range of applications would be guaranteed
  • Frameworks / CMS would profit from seamlessly integrating best-of-breed applications in their overall solution
  • Dedicated applications (forums, commerce, photo album, ...) would find their way into more CMS'
  • The end-user profits from better overall solutions
  • Tools common to all integrations could be developed

They key requirements at master applications is the event or hooking system. Without, only a low-tech fallback solution like on-the-fly user creation with periodic synchronization runs is possible. How this event system is implemented, does not matter at all.

The slave applications must expose a well-defined interface or protocol. The details of such an interface are not that important (for now, we can always improve the standardization at a later point), as long as the interface follows the same basic principles to offer functions to initialize, handle the request, create a user, etc.

If all interfaces were standardized one could assemble a CMS that has a feature-rich forum, gallery etc. by just writing a little glue-code. Seeing each CMS writing their own (mostly poor in features) forum solution or multimedia framework and thus wasting their own resources and making users less happy than with feature-rich solutions is reason enough for such a standard.

A standard should have different levels, meaning that not all applications can meet all goals of such a standard, but they should still work together, just on a lower level of standardization.

CMS devs usually want to develop their own solution, favor their own forum or gallery solution etc since they believe that one day, they'll have all the features needed, plus it's then an integral part of their CMS, well desgined and their code is better anyway :) Of course we have to accept and appreciate this position, but with integration/interoperability standards, applications could achieve the same, without having to develop specialized solutions like a forum system.

支持基于事件整合的应用程序

As a master application:

  • Gallery2 (90% events / hooks for user / group create / update / delete, logout, login, ..missing: configuration changes)
  • Xaraya (100% events / hooks for user / group create / update / delete, configuration changes, logout, login, ..)
  • Wordpress (90% events / hooks for user / update / delete, rewrites, logout, login, ..)
  • Drupal (80% maybe?)
  • Joomla (100% joomla 1.5; login, logout, create, update, delete user, block, activation, system before and after start)
  • Typo3 (50% maybe?, e.g. no unified create user event / hook)
  • TikiPro (?%)
  • ...

As a slave application:

  • Gallery 2
  • Phorum.org
  • Pretty all scripts, since you can always add a layer / interface which calls the internal functions and add output buffering around it. But they need to provide basic means to dictate the URL format etc.

参考

Event-based loose integration is an obvious and the most prominent approach to software integration for a long time now. These are a few papers and references on the topic:

More links specific to web / PHP interoperability: