我正在尝试使用Glassfish服务器实现Java EE websockets,而且我已经掌握了基础知识。
至于我目前的项目,我想在游戏中实现服务器“滴答”,每隔几毫秒更新一次服务器,以便连接到服务器的所有会话看到相同的东西。
但是,我不知道从哪里开始使用Glassfish。我知道我从头开始创建一个服务器并实现一个计时器方法,但如果可能的话,我宁愿在这里保存一些工作。
简单地说,在glassfish服务器中实现定时器/滴答机制是否容易(假设它正在运行)?
例如,我想让服务器在通过websocket连接后定期向客户端HTML页面发送单词“hello”。
答案 0 :(得分:1)
短版
我们用三个类来解决它:
带代码的长版本
现在代码中,1)是Mike在评论中提到的:一个典型的调度程序,可以触发一些事件。这个课程基本上是一个时钟,无论谁正在听它的事件。我们有一个EAR = EJB + WAR项目。我们的计时器在EJB模块中,但是如果你有一个WAR,你可以把它放在那里。
// some import
import javax.enterprise.event.Event;
@Singleton
@Startup
public class TimerBean {
@Inject
private Event<TickEvent> tickEvent;
@Schedule(hour = "*", minute = "*", second = "*/5")
public void printSchedule() {
tickEvent.fire(new TickEvent(/*...your initialization...*/));
}
public class TickEvent{
// we have some info here but you can
// leave it empty.
}
}
对于2)websocket端点,这是一个非常学术的终点。不要忘记一个连接=一个端点实例。您可以使用session.getOpenedSessions()
找到来自给定会话的所有已打开会话,但我将在下一部分解释为何使用处理程序。
// some import
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
@ServerEndPoint(value = "/myEndPointPath")
public class TickEndPoint{
@Inject
private TickSessionHandler sessionHandler;
@OnOpen
public void onOpen(Session session){
sessionHandler.addSession(session);
}
@OnClose
public void onClose(Session session, CloseReason reason){
sessionHandler.removeSession(session);
}
}
现在是keystone:会话处理程序。会话处理程序是ApplicationScoped bean,因此它始终可用。我使用它的原因是:
@Observes(notifyObserver = Reception.IF_EXISTS)
修复了它,但我们遇到了其他EJB问题,我将在2中详细说明。另外,在我们的特殊情况下,我们有一些观点,您可能会在以后见面。
我遇到了一些教程/详细信息,其中@ServerEndPoint被注释为@ApplicationScoped。按设计(一个服务器端点=一个websocket连接),我觉得不舒服所以我拒绝实施这个解决方案
@Named
@ApplicationScoped
public class TickSessionHandler{
// There is no need to have a static Set, worst,
// containers don't like it
public Set<Session> SESSIONS;
// let's initialize the set
public TickSessionHandler{
this.SESSIONS = new HashSet<>();
}
// ---------- sessions management
public void addSession(Session session){
this.SESSIONS.add(session);
}
public void removeSession(Sesssion session){
this.SESSIONS.remove(session);
}
// ---------- Listen to the timer
public void onTick(@Observes TickEvent event){
// if required, get the event attribute
// and proceed
// your request:
this.SESSIONS.forEach(session -> {
session.getBasicRemote().sendText("hello");
});
}
}
希望这有帮助。解释似乎很长,但核心实现实际上非常轻。 AFAIK,这种要求没有捷径。