ReverseAjax,Phần5: Phát triểnwebtheohướngsựkiện
Các thuật ngữ
Bạn có thể đã quen với kiến trúc hướngsự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átsự 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átsự 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átsự 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 theohướngsự 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 theohướngsự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ướngsự 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ướngsự 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ướngsự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ướngsự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áttriển và bảo trì ứng dụng. Với các giải pháp hướngsự 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ướngsự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ướngsự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ướngsự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ướngsựkiện có thể được áp dụng bên phía máy khách để pháttriể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áttriể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ướngsự
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 theohướngsự 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 theohướngsựkiện và ReverseAjax, 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 theohướngsự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 ReverseAjax, 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 theohướngsự 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 theohướngsự 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áttriể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áttriể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ểntheohướ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.
. 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. 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