2010-07-17 6 views
8

Tôi đang xây dựng trang web cộng đồng bằng grails (sử dụng Apache Shiro cho hệ thống bảo mật và xác thực) và tôi muốn triển khai tính năng "đang trực tuyến?".Làm thế nào để dễ dàng thực hiện "ai đang trực tuyến" trong Grails hoặc ứng dụng Java?

Url này http://cksource.com/forums/viewonline.php (xem ảnh chụp bên dưới nếu bạn không có quyền truy cập vào Url này) cho ví dụ về những gì tôi muốn đạt được.

Làm cách nào tôi có thể làm điều đó một cách đơn giản nhất? Có giải pháp hiện có nào trong Grails hay trong Java không?

Cảm ơn bạn.

Snapshot: Snapshot of Who is online page http://www.freeimagehosting.net/uploads/th.2de8468a86.png hay thấy ở đây: http://www.freeimagehosting.net/image.php?2de8468a86.png

+0

URL này yêu cầu đăng nhập, vì vậy nó vô dụng cho bất cứ ai không phải là hoặc sẽ không đăng ký trên trang web đó. – BalusC

+0

@BalusC Câu hỏi được cập nhật – fabien7474

Trả lời

21

Bạn cần phải thu thập tất cả người dùng đăng nhập trong một Set<User> trong ứng dụng phạm vi. Chỉ cần móc vào loginlogout và thêm và xóa User tương ứng. Về cơ bản:

public void login(User user) { 
    // Do your business thing and then 
    logins.add(user); 
} 

public void logout(User user) { 
    // Do your business thing and then 
    logins.remove(user); 
} 

Nếu bạn đang lưu trữ người dùng đã đăng nhập trong phiên, thì bạn muốn thêm một móc khác trên phiên hủy để đăng xuất khỏi bất kỳ người dùng đã đăng nhập nào. Tôi không chắc chắn về cách Grails phù hợp trong hình ảnh, nhưng nói trong Java Servlet API, bạn muốn sử dụng HttpSessionListener#sessionDestroyed() cho việc này.

public void sessionDestroyed(HttpSessionEvent event) { 
    User user = (User) event.getSession().getAttribute("user"); 
    if (user != null) { 
     Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins"); 
     logins.remove(user); 
    } 
} 

Bạn cũng có thể chỉ cần để mô hình User triển khai HttpSessionBindingListener. Các phương thức được triển khai sẽ được gọi tự động bất cứ khi nào cá thể User được đưa vào phiên làm việc hoặc bị loại bỏ khỏi nó (điều này cũng sẽ xảy ra khi hủy phiên).

public class User implements HttpSessionBindingListener { 

    @Override 
    public void valueBound(HttpSessionBindingEvent event) { 
     Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins"); 
     logins.add(this); 
    } 

    @Override 
    public void valueUnbound(HttpSessionBindingEvent event) { 
     Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins"); 
     logins.remove(this); 
    } 

    // @Override equals() and hashCode() as well! 

} 
+0

Có lẽ cũng thêm hợp đồng thuê và làm mới nó khi hành động của người dùng để lọc ra các phiên không hoạt động mà không có đăng xuất thích hợp. –

+0

Điều gì xảy ra nếu người dùng không đăng xuất một cách rõ ràng nhưng chỉ đóng trình duyệt của họ? –

+0

@Partly và @Burt: chỉ cần hooking vào phá hủy phiên servletcontainer được quản lý như được mô tả trong đoạn cuối là đủ. – BalusC

2

này đã được thảo luận một số thời gian trước đây trên mailing list: http://grails.1312388.n4.nabble.com/Information-about-all-logged-in-users-with-Acegi-or-SpringSecurity-in-Grails-td1372911.html

+0

Cảm ơn bạn Stefan.Tuy nhiên, các chủ đề bạn đang chỉ là về Spring Security và tiếc là tôi đang sử dụng Shiro. – fabien7474

+0

Xin chào Fabien, tôi đã không đọc kỹ điều đó một cách cẩn thận - liên kết mà tôi đã đăng chỉ hoạt động với acegi. –