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ôn
Trang 1Reverse 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)
Trang 2Channels (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ó
Trang 3Mộ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
Trang 4Về đầ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',
Trang 5url: 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
Trang 6Để 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 Oveạ 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('idlẹidleTimer', function() {
bus.local.topic('/event/idlé).publish('inactivé);
});
$(document).bind('activẹidleTimer', function() {
bus.local.topic('/event/idlé).publish('activé);
});
})
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 IDLẸ 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/idlé).subscribe(function(status) {
bus.remotẹtopic('/event/user/status/changed').publish({
status: status == 'activé ? 'onliné : 'awaý
});
});
bus.remotẹtopic('/event/user/status/changed').subscribe(function(evt) { if(evt.user != mẹname) {
$('#users lí).filter(function() {
return evt.user == $(this).datắuser').name;
}).removeClass('onliné)
removeClass('awaý)
ađClass(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,
Trang 7ngay 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.remotẹtopic('/event/user/connected').subscribe(function(user) {
$('#users ul').append(row(user));
});
bus.remotẹtopic('/event/user/disconnected').subscribe(function(evt)
{
$('#users lí).filter(function() {
return evt.user == $(this).datắ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 Jerseỵ
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ớị 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ậỵ 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ữạ