Bạn có thể đã quen với kiến trúc hướng sự kiện (Event-Driven Architecture - EDA), các hệ 
thống EventBus, hệ thống thông báo, xử lý sự kiện phức tạp (CEP) và các kênh (channel). Các 
thuật ngữ và khái niệm này đã tồn tại trong nhiều năm nay. Có thể bạn sẽ nghe thấy chúng nhiều 
hơn một khi công nghệ này hoàn thiện. Phần này cung cấp các giải thích ngắn gọn về các thuật 
ngữ này.
                
              
                                            
                                
            
                       
            
                 7 trang
7 trang | 
Chia sẻ: lylyngoc | Lượt xem: 1830 | Lượt tải: 1 
              
            Bạn đang xem nội dung tài liệu Reverse Ajax, Phần 5: Phát triển web theo hướng sự kiện, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Reverse Ajax, Phần 5: Phát triển web theo hướng sự kiện 
Các thuật ngữ 
Bạn có thể đã quen với kiến trúc hướng sự kiện (Event-Driven Architecture - EDA), các hệ 
thống EventBus, hệ thống thông báo, xử lý sự kiện phức tạp (CEP) và các kênh (channel). Các 
thuật ngữ và khái niệm này đã tồn tại trong nhiều năm nay. Có thể bạn sẽ nghe thấy chúng nhiều 
hơn một khi công nghệ này hoàn thiện. Phần này cung cấp các giải thích ngắn gọn về các thuật 
ngữ này. 
Event (Sự kiện) 
Một sự kiện xảy ra trong một hệ thống. Nó thường có các thông số kèm theo, chẳng hạn 
như thời điểm xảy ra (timestamp), nguồn hoặc địa điểm (thành phần được click vào) và 
một số thông tin mô tả sự kiện. Một sự kiện có thể có nhiều thông số tùy theo hệ thống. 
Event-processing architecture (EDA - Kiến trúc xử lý sự kiện) 
Cũng được gọi là lập trình dựa trên sự kiện, đây là một thiết kế kiến trúc, nơi ứng dụng 
của bạn có chứa các thành phần truyền thông và thực hiện bằng cách gửi và nhận sự kiện. 
Giao diện người dùng đồ họa (GUI) Swing của Java là một ví dụ về EDA. Mỗi thành 
phần của Swing có thể lắng nghe các sự kiện, tác động lại chúng, gửi các sự kiện khác và 
v.v.... EDA được tạo nên bởi những phần nhỏ: nơi xuất phát sự kiên, nơi tiếp nhận sự 
kiện, các sự kiện và phần mềm xử lý xự kiện. 
 Event producer (Nơi xuất phát sự kiện) - Thành phần này ban hành các sự kiện. 
Trong ví dụ trong bài này, một button dùng để gửi đi các biểu mẫu chính là nơi 
xuất phát sự kiện. 
 Event consumer (Nơi tiếp nhận sự kiện) - Là một thành phần lắng nghe các sự 
kiện cụ thể được gửi đi. Ví dụ, trong trường hợp gửi biểu mẫu, trình duyệt sẽ lắng 
nghe các lần nhấn chuột trên button để gửi dữ liệu biểu mẫu đến máy chủ. 
 Event-processing software (Phần mềm xử lý sự kiện) - Chính là lõi của hệ 
thống, nơi các Event producer gửi đi các sự kiện và Event consumer đăng ký để 
tiếp nhận sự kiện. Tùy thuộc vào phần mềm mà việc xử lý có thể đơn giản (như 
chỉ cần chuyển tiếp các sự kiện tới nơi tiếp nhận) hoặc phức tạp (CEP). Với CEP, 
phần mềm hỗ trợ một loạt các phương tiện xử lý, chẳng hạn như tổng hợp, lọc và 
biến đổi sự kiện. 
Esper là một ví dụ về phần mềm như vậy. Phần mềm xử lý sự kiện không chỉ đại 
diện cho một ứng dụng chạy độc lập, mà nó còn có thể là một thư viện được tích 
hợp trong ứng dụng của bạn. 
Messaging systems (Các hệ thống Messaging) 
Một loại ứng dụng theo hướng sự kiện, nơi mà các Event producer gửi đi các thông điệp 
tới các kênh và tới những Event consumer đã đăng ký với kênh đó. Event producer và 
Event consumer không có mối liên kết mà hoàn toàn độc lập. Đối với loại ứng dụng này, 
bạn thường sử dụng thuật ngữ message (thông điệp) thay cho event (sự kiện). 
Channels (Các kênh) 
Là một cách để phân loại sự kiện trong một hệ thống Messaging. Chúng đại diện cho 
điểm đến, nơi các Event producer muốn gửi sự kiện tới. Ví dụ, trong một ứng dụng 
phòng chat, một kênh sẽ là /chatapplication/chatrooms/asdrt678. Kênh này sẽ xác định 
một phòng chat cụ thể, nơi các Event producer có thể gửi thông báo tới và là nơi mà 
thành phần đồ họa sẽ hiển thị thông báo mới đến đó. 
Một số hệ thống Messaging cung cấp hai loại kênh: queue (hàng đợi) và topic (chủ đề). 
 Các Queue (hàng đợi) - Khi một thông điệp được chuyển đến một hàng đợi thì 
chỉ có một Event consumer nhận được và xử lý nó. Những Event consumer khác 
sẽ không nhìn thấy nó. Các hàng đợi có thể được tạo ra liên tục để đảm bảo phân 
phối thông tin. Ví dụ ta có một yêu cầu gửi email. Một ứng dụng web sẽ gửi một 
thông điệp tới hàng đợi /myapp/mail/user-registration khi người dùng đăng ký. Có 
thể sẽ có một số ứng dụng gửi email tiếp tục được đăng ký vào hàng đợi này. Nếu 
không thì thông điệp sẽ không mất đi. 
 Các Topic (chủ đề) - Khi một thông điệp được chuyển đến một topic thì tất cả 
những người đăng ký đều nhận được được thông điệp. Một topic thường không 
liên tục. Ví dụ về một topic: /event/system/cpu/usage, nơi một trình sản xuất 
thường xuyên gửi đi các thông số sử dụng CPU. Ở phía bên kia, nếu như ai quan 
tâm thì họ có thể đăng ký để nhận thông tin này. 
Publish/Subcribe (Xuất bản/đăng ký) 
Các giải pháp theo hướng sự kiện được thực hiện mẫu xuất bản/đăng ký. Các Event 
producer xuất bản các sự kiện bằng phần mềm xử lý và Event consumer đăng ký để nhận 
chúng. Cách mà Event consumer đăng ký phụ thuộc vào phần mềm. Trong các ứng dụng 
gửi thông điệp, họ đăng ký theo các kênh (ví dụ, theo tùy chọn cũng áp dụng các quy tắc 
lọc dựa vào kiểu sự kiện). Với một CEP như Esper, việc đăng ký có thể được thực hiện 
thông qua một yêu cầu giống như SQL để xác định những sự kiện mà bạn đang quan tâm. 
Về đầu trang 
Vì sao chúng ta sử dụng các giải pháp hướng sự kiện? 
Theo các cách giao tiếp truyền thống, nếu hệ thống A yêu cầu thông tin từ hệ thống B, thì yêu 
cầu sẽ được gửi đến B. Hệ thống B sẽ xử lý yêu cầu đó và hệ thống A sẽ chờ phản hồi. Khi xử lý 
xong, phản hồi sẽ được gửi trở lại hệ thống A. Trong cơ chế giao tiếp đồng bộ, việc tiêu thụ tài 
nguyên không hiệu quả do mất thời gian xử lý trong khi chờ phản hồi. 
Trong chế độ không đồng bộ, hệ thống A sẽ đăng ký thông tin mà họ muốn từ hệ thống B. Sau 
đó, theo tùy chọn hệ thống A sẽ gửi một thông báo tới hệ thống B, rồi ngay lập tức quay trở lại 
và hệ thống A có thể xử lý những việc khác. Bước này là tùy chọn. Thông thường, trong các ứng 
dụng hướng sự kiện, bạn không phải yêu cầu hệ thống khác gửi các sự kiện bởi vì bạn không biết 
chúng đang có những gì. Khi hệ thống B gửi phản hồi, hệ thống A ngay lập tức nhận được nó. 
Một lợi thế của kiến trúc hướng sự kiện là ở chỗ nó cho phép khả năng co giãn tốt hơn. Khả năng 
co giãn là khả năng mà hệ thống có thể thích ứng với một sự thay đổi theo yêu cầu, khối lượng 
hoặc cường độ trong khi vẫn đáp ứng được các mục tiêu của nó. Bằng cách loại bỏ các lần tạm 
dừng, các kiến trúc hướng sự kiện thường hoạt động tốt hơn và có tốc độ xử lý cao hơn. 
Một lợi thế khác nằm trong việc phát triển và bảo trì ứng dụng. Với các giải pháp hướng sự kiện, 
mỗi thành phần trong ứng dụng của bạn có thể hoàn toàn được cô lập riêng biệt. 
Các giải pháp hướng sự kiện cho phép thời gian đáp ứng tốt nhất do có độ trễ truyền thông thấp 
hơn. 
Về đầu trang 
Áp dụng các giải pháp hướng sự kiện cho web 
Các web framework được sử dụng dựa trên mẫu yêu cầu-đáp ứng truyền thống là nguyên nhân 
của việc refresh trang web liên tục. Với sự xuất hiện của Ajax, Reverse Ajax và các framework 
mạnh mẽ khác như CometD và Atmosphere, giờ đây chúng ta dễ dàng áp dụng các khái niệm về 
kiến trúc hướng sự kiện cho trang web để có được những lợi ích trong việc tách rời các thành 
phần, khả năng co giãn và khả năng đáp ứng. 
Về phía máy khách 
Kiến trúc hướng sự kiện có thể được áp dụng bên phía máy khách để phát triển GUI. Thay vì tạo 
ra một trang web truyền thống, bạn có thể có một trang web riêng đóng vai trò như một 
container. Mỗi thành phần (từng phần trong trang) có thể được cách ly. Bạn có thể có một GUI 
Swing của Java trên trang web, giống như một trang Google có chứa các tiện ích nhỏ (xem phần 
Tài nguyên để biết thêm chi tiết). 
Bạn sẽ cần một event bus (bus sự kiện). Ví dụ, bạn có thể phát triển event bus JavaScript, để cho 
phép mỗi thành phần của trang đăng ký và xuất bản các kênh. Các sự kiện này cũng có thể được 
đồng bộ hóa để kích hoạt các hành động sau khi nhận được hai hoặc nhiều sự kiện hơn. Có thể 
sử dụng event bus cho các sự kiện cục bộ trong một trang, nhưng bạn cũng có thể thêm vào các 
plugin để hỗ trợ các sự kiện từ xa bằng cách sử dụng CometD hoặc Socket.IO. 
Về phía máy chủ 
Ở phía máy chủ, bạn sẽ cần thiết lập một framework Reverse Ajax hỗ trợ kiến trúc hướng sự 
kiện. Trong số những framework đã xem xét trong các phần trước của loạt bài này, chỉ có 
CometD có cách tiếp cận theo hướng sự kiện. Đối với các framework khác, bạn sẽ cần phải thêm 
các tùy chỉnh hỗ trợ, điều này rất quan trọng. Bạn cũng có thể thêm vào một hệ thống thông báo 
của bên thứ ba như JMS (ví dụ, ActiveMQ của Apache) hoặc một CEP như Esper. Một giải pháp 
đơn giản hơn là Redis, hỗ trợ các công việc xuất bản/đăng ký cơ bản. 
Loạt bài này nói về web theo hướng sự kiện và Reverse Ajax, vì vậy chúng tôi sẽ tập trung vào 
phần máy khách và sẽ không thiết lập một hệ thống thông báo phức tạp. 
Về đầu trang 
Ví dụ web theo hướng sự kiện 
Ví dụ mà bạn sẽ tạo ra cùng với bài này là một ứng dụng phòng chat trên nền web, có một khung 
cửa sổ người dùng chứa danh sách những người bạn đã kết nối. Tên bạn bè của bạn sẽ được in 
đậm, những người đang hoạt động (sau 20 giây) sẽ có màu xanh lá cây còn những người không 
hoạt động sẽ có màu cam. Nếu một người dùng kết nối hoặc ngắt kết nối, danh sách sẽ được làm 
mới. 
Đối với các mục đích bảo mật, người ta cấu hình một thời gian chờ hai phút của phiên làm việc 
trong tệp web.xml. Nếu sau hai phút không hoạt động, sẽ có một cửa sổ thông báo xuất hiện và 
bạn sẽ được chuyển hướng đến trang đăng nhập. 
Bạn được chuyển hướng lại đến trang đăng nhập ngay khi bạn không có thêm phiên làm việc nào 
hoặc nếu bạn vẫn chưa được kết nối. Trang đăng nhập yêu cầu thông tin của bạn và kiểm tra xem 
liệu bạn đã sẵn sàng đăng nhập vào phòng chat chưa. 
Sau khi đăng nhập, bạn có thể gửi một tin nhắn trong phòng chat cho tất cả bạn bè. Một giao 
diện điều khiển cũng có mặt và ghi lại tất cả các sự kiện nhận được. 
Ứng dụng web được dựa trên sự kiện. Với thông tin trên, bạn có thể dễ dàng định nghĩa một số 
sự kiện: 
 Một người dùng được kết nối. 
 Một người dùng được ngắt kết nối. 
 Phiên làm việc đã kết thúc. 
 Một tin nhắn nhận được. 
 Một bộ lọc bảo mật để chặn các yêu cầu nếu bạn chưa đăng nhập. 
 Một người dùng chuyển sang trạng thái không hoạt động. 
 Một người dùng chuyển sang trạng thái hoạt động. 
 Tất cả các sự kiện khác liên quan đến phối hợp giao diện người dùng. 
Một số sự kiện chỉ là cục bộ trong ứng dụng web. Chúng được xác định bởi một bus cục bộ, như 
thể hiện trong Liệt kê 1: 
Liệt kê 1. Thiết lập bus 
bus = { 
 local: new EventBus({ 
 name: 'EventBus Local' 
 }), 
 remote: EventBus.cometd({ 
 name: 'EventBus Remote', 
 logLevel: 'warn', 
 url: document.location.href.substring(0, 
 document.location.href.length - 
 document.location.pathname.length) + '/async', 
 onConnect: function() { 
 bus.local.topic('/event/bus/remote/connected').publish(); 
 }, 
 onDisconnect: function() { 
 bus.local.topic('/event/bus/remote/disconnected').publish(); 
 } 
 }) 
}; 
Đối với các sự kiện từ xa khác, chúng cần một hệ thống Reverse Ajax, như CometD, được xuất 
bản giữa tất cả các máy khách. Hình 1 cho thấy ứng dụng ví dụ. 
Hình 1. Ứng dụng ví dụ 
Bạn có thể tải về ứng dụng ví dụ. Nhiều lớp đại diện cho các lớp bảo mật hoặc dùng để quản lý 
phiên làm việc người dùng. Bài này chỉ ra những phần quan trọng nhất của mã này, bạn nên tải 
về và chạy thử ví dụ để thấy cách nó làm việc. 
Ứng dụng web được tạo nên bằng các thành phần khác nhau: một phòng chat, danh sách người 
dùng và giao diện điều khiển. Mỗi thành phần hoàn toàn độc lập và có thể bị loại bỏ mà không 
ảnh hưởng đến những thành phần khác. 
Để thiết lập hệ thống theo hướng sự kiện, cục bộ và từ xa, ví dụ này sử dụng hệ thống EventBus 
của Ovea. Nó cung cấp một event bus cục bộ, một cầu nối cho CometD để có các sự kiện từ xa 
và là một cách để phối hợp các sự kiện (để kích hoạt các hành động sau khi đã hoàn thành một số 
sự kiện). Tất nhiên, bạn có thể thay một hệ thống khác, nếu bạn chọn. Ví dụ này được viết bằng 
JavaScript, như thể hiện trong Liệt kê 1. 
Một khi những bus này đã sẵn sàng sử dụng, ứng dụng và các thành phần là dựa vào sự kiện. 
Trong ví dụ này, hệ thống phát hiện IDLE được thiết lập như trong Liệt kê 2: 
Liệt kê 2. Hệ thống phát hiện IDLE 
bus.local.topic('/event/dom/loaded').subscribe(function() { 
 $.idleTimer(20000); 
 $(document).bind('idle.idleTimer', function() { 
 bus.local.topic('/event/idle').publish('inactive'); 
 }); 
 $(document).bind('active.idleTimer', function() { 
 bus.local.topic('/event/idle').publish('active'); 
 }); 
}) 
Với mã trong Liệt kê 2, hệ thống IDLE gửi các sự kiện khi nó phát hiện ra một hành động. Có 
thể sử dụng mã này trong bất kỳ ứng dụng nào đòi hỏi một hệ thống IDLE. Trong trường hợp 
này, bạn cần chuyển dịch nó theo các sự kiện từ xa cho hoạt động của người dùng. Nó cũng được 
thực hiện bằng JavaScript, như thể hiện trong Liệt kê 3: 
Liệt kê 3. Quản lý hoạt động người dùng 
bus.local.topic('/event/idle').subscribe(function(status) { 
 bus.remote.topic('/event/user/status/changed').publish({ 
 status: status == 'active' ? 'online' : 'away' 
 }); 
}); 
bus.remote.topic('/event/user/status/changed').subscribe(function(evt) { 
 if(evt.user != me.name) { 
 $('#users li').filter(function() { 
 return evt.user == $(this).data('user').name; 
 }).removeClass('online') 
 .removeClass('away') 
 .addClass(evt.status); 
 } 
}); 
Việc đăng ký đầu tiên nhận được các sự kiện từ hệ thống IDLE và gửi trạng thái người dùng đến 
máy chủ. Việc đăng ký khác đã nhận được các sự kiện trạng thái người dùng từ máy chủ. Vì vậy, 
ngay khi một trạng thái người dùng thay đổi, màu sắc của danh sách người dùng thay đổi sang 
màu xanh hoặc màu cam. 
Khi một người dùng kết nối hoặc ngắt kết nối, một sự kiện được gửi đi, như thể hiện trong Liệt 
kê 4: 
Liệt kê 4. Quản lý danh sách người dùng 
bus.remote.topic('/event/user/connected').subscribe(function(user) { 
 $('#users ul').append(row(user)); 
}); 
bus.remote.topic('/event/user/disconnected').subscribe(function(evt) 
{ 
 $('#users li').filter(function() { 
 return evt.user == $(this).data('user').name; 
 }).remove(); 
}); 
Những đoạn mã trong ứng dụng rất đơn giản, được tách riêng và được cô lập. Bằng cách sử dụng 
lại nhiều công nghệ Ovea bạn có thể nhanh chóng tạo ra các ứng dụng web theo hướng sự kiện. 
Tuy nhiên, điều đó không cần thiết do hệ thống khác có thể được theo cách của nó. Ví dụ này chỉ 
mất một ngày phát triển và một nửa của nó là những đoạn mã thiết yếu, bao gồm: 
 Maven, để xây dựng dự án. 
 Các tính năng bảo mật (đăng nhập, đăng xuất, thời gian chờ phiên làm việc). 
 Các dịch vụ RES khi sử dụng Jersey. 
Về đầu trang 
Kết luận 
Loạt bài này đã chỉ ra cách xây dựng các ứng dụng có thể đáp ứng và có thể co giãn linh động, 
cung cấp một trải nghiệm người dùng tốt. Các ứng dụng web dựa trên sự kiện là một khái niệm 
khá mới. Một số web framework sử dụng chúng trong nội bộ, nhưng bài này đã cho thấy rằng 
bạn không cần một web framework để xây dựng một ứng dụng như vậy. Việc sử dụng thư viện 
tốt chuyên biệt thì phù hợp hơn so với việc phân định trách nhiệm giữa các nhà phát triển Java và 
thiết kế web. Hy vọng rằng giờ đây bạn đã có hiểu biết nhất định về cách phát triển theo hướng 
sự kiện và biến nó trở thành thói quen của mình. Nó có sức hút mạnh mẽ và khi bạn quyết định 
áp dụng, có thể bạn sẽ không muốn quay trở về với các framework truyền thống nữa.