我使用GlassFish Server 4.1/Java EE 7。因此,Tyrus WebSocket实现是现成的。
在Java EE应用程序中有一个场景,其中用户和管理员共同执行CRUD操作。"插入"操作由注册用户执行,其余操作在需要时由管理员处理。
例如,反馈由注册用户提交(因此,通过其关联的JPA实体Feedback
插入)(仅在登录之后)。"Update"(基本上只有testimonials
)和"delete"由管理员在需要时(在他自己的会话中)执行。
因此,这些操作在不同的会话中执行,需要不同的身份验证/授权。为此,需要两个不同的WebSockets端点,例如
@ServerEndpoint("/Admin/Push")
和
@ServerEndpoint("/User/Push")
而不是使用两个不同的类,如
@ServerEndpoint("/Admin/Push") // This is a secured endpoint requiring admin's privileges.
public final class AdminPush {
private static final Set<Session> sessions = new LinkedHashSet<Session>();
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
}
@OnClose
public void onClose(Session session) {
sessions.remove(session);
}
@OnMessage
public void onMessage(String text) {
// Notify all users.
// Since modifications to entities are done on the server side,
// it is basically another synchronized static method notifying all users.
}
}
和
@ServerEndpoint("/User/Push") // This is a secured endpoint requiring user's privileges.
public final class UserPush {
private static final Set<Session> sessions = new LinkedHashSet<Session>();
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
}
@OnClose
public void onClose(Session session) {
sessions.remove(session);
}
@OnMessage
public void onMessage(String text) {
// Notify all users.
// Since modifications to entities are done on the server side,
// it is basically another synchronized static method notifying all users.
}
}
是否允许将它们组合成一个类,例如?
@ServerEndpoint("/Admin/Push")
@ServerEndpoint("/User/Push")
public final class Push {}
从理论上讲,这只是一个想法来说明是否允许以这种想象的方式组合它们。实际上,这显然是一个编译时错误,因为@ServerEndpoint
不是一个可重复的注释。
在上述任何一种情况下,当管理员或用户在Feedback
JPA实体(通过WebSockets实时更新)中修改某些内容时,都会通知用户。Feedback
对所有用户公开可用,包括匿名用户,但只能由注册用户提交(它也会定期更新,但这是另一回事)。
也许,您可以这样做:
@ServerEndpoint("/{profile}/push")
public final class Push {}
或者从业务分离的角度来看,您应该创建一个或多个类来管理会话或公共操作,而入口点类只需要调用这些公共方法。比如:
@ServerEndpoint("/admin/push")
public final class Admin {
@OnOpen
public void onOpen(Session session) {
// Call session manager
}
}
@ServerEndpoint("/user/push")
public final class User {
@OnOpen
public void onOpen(Session session) {
// Call session manager
}
}
public class SessionManager {
// Your methods
}
我有几个想法