Zkoss:如何通知用户会话超时或与服务器的连接丢失
Zkoss: How to notify user of session timeout or lost connection to server?
在使用zkoss web UI框架时,是否有一种编程检查会话超时或连接丢失的方法?问题是,即使我关闭了服务器、重新部署或重新启动它,UI也会一直显示在浏览器中。
用户只有在尝试与UI交互(例如单击按钮)时才会发现问题。它要么弹出会话超时信息,要么弹出服务器无法访问信息。
我正在寻找的是客户端能够立即(或在合理短的时间内)通知用户的东西。例如,当会话丢失、服务器关闭或无法访问时,会显示一个弹出窗口,"告诉"用户有什么问题(这样他就可以立即刷新或采取其他操作)。
我在看医生,但他们没有说任何具体的情况。会话设置包括限制,保持活动以防止会话超时,但仅此而已
我正在考虑一些定制的javascript,它会定期ping服务器(也许是一个特殊的servlet,它也会让脚本知道会话超时),但我更喜欢zk框架的原生版本。当连接丢失时,zk计时器组件似乎停止了功能,但它不会触发错误弹出窗口。
我稍后将发布代码,说明如何为所有登录的客户端分发消息。
同时,以下是您可以实现的代码,以便在会话超时即将激活之前通知用户(不用于服务器重启):
SessionTimeOutExecListener.java:
public class SessionTimeOutExecListener implements ExecutionInit, UiLifeCycle {
private String timerId = "timeoutNotifyTimer";
public void init(Execution exec, Execution parent) throws Exception {
Timer timer = (Timer) exec.getDesktop().getAttribute(timerId);
if (timer != null) {
if (isSendbyMsgBox(timer, exec))
return;
timer.stop();
timer.start();
}
}
private boolean isSendbyMsgBox(Timer timer, Execution exec) {
HttpServletRequest hreq = (HttpServletRequest)exec.getNativeRequest();
for (int j = 0;; ++j) {
final String uuid = hreq.getParameter("uuid_"+j);
if (uuid == null)
break;
if (uuid.equals(timer.getUuid()))
return true;
}
return false;
}
public void afterComponentAttached(Component comp, Page page) {
}
public void afterComponentDetached(Component comp, Page prevpage) {
}
public void afterComponentMoved(Component parent, Component child,
Component prevparent) {
}
public void afterPageAttached(Page page, Desktop desktop) {
Object obj = desktop.getAttribute(timerId);
if (obj == null) {
int tmout = desktop.getWebApp().getConfiguration()
.getSessionMaxInactiveInterval();
final Timer timer = new Timer((tmout - 2) * 1000);
timer.addEventListener(Events.ON_TIMER, new EventListener() {
public void onEvent(Event event) throws Exception {
Messagebox.show("Your session are about to be expired",
"Information", Messagebox.OK,
Messagebox.INFORMATION, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
if (Messagebox.ON_OK.equals(event.getName())){
timer.start();
}
}
});
}
});
timer.setPage(page);
desktop.setAttribute(timerId, timer);
timer.start();
}
}
public void afterPageDetached(Page page, Desktop prevdesktop) {
}
}
zk.xml:
<listener>
<listener-class>test.MyExecListener</listener-class>
</listener>
编辑:
正如我所说,这是用于向所有活动会话发送消息的代码
首先是一个可以发送消息的简单页面。
message.zul:
<?xml version="1.0" encoding="UTF-8"?>
<window xmlns="http://www.zkoss.org/2005/zul" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('be.chillworld.MessageVM')" width="100%" height="100%">
<textbox value="@bind(vm.message)"/>
<button onClick="@command('sendMessage')" label="Send"/>
</window>
正如您所看到的,它是MVVM,但不要担心,您也可以将其插入MVC项目中,因为我使用EventQueue
然后,我们需要所有页面的监听器,因此最佳实践是创建一个抽象VM或扩展您使用的Composer。
AbstractVM.java:
package be.chillworld;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.util.Clients;
/**
*
* @author chillworld
*/
public abstract class AbstractVM {
@Init
public void abstractInit() {
EventQueues.lookup("globalMessage", EventQueues.APPLICATION, true).subscribe(new EventListener<Event>() {
public void onEvent(Event event) throws Exception {
if ("onSendMessage".equals(event.getName())) {
Clients.showNotification(String.valueOf(event.getData()));
}
}
});
}
}
因此,当我们得到活动时,这实际上就是我们要做的
如果你想制作一个基本的作曲家,你可以这样做:
BasicComposer.java:
package be.chillworld;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.util.Clients;
/**
*
* @author chillworld
*/
public class BasicComposer extends SelectorComposer<Component> {
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
EventQueues.lookup("globalMessage", EventQueues.APPLICATION, true).subscribe(new EventListener<Event>() {
public void onEvent(Event event) throws Exception {
if ("onSendMessage".equals(event.getName())) {
Clients.showNotification(String.valueOf(event.getData()));
}
}
});
}
}
不要忘记为每个视图扩展BasicComposer
或AbstractVM
这就是为什么我问你是否使用页面模板,如果你为每个页面都有一个主模板,你只需将其插入其中,每个页面都会订阅eventlistener,所以你不必使用BasicComposer
或AbstractVM
好的,现在我们为message.zul.创建视图模型
消息VM.java:
package be.chillworld;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.util.Clients;
/**
*
* @author chillworld
*/
public class MessageVM extends AbstractVM {
private String message;
@Init(superclass = true)
public void init(){}
@Command
public void sendMessage () {
if (message==null || message.trim().isEmpty()) {
Clients.showNotification("Please enter something to send.");
} else {
System.out.println("posting event");
EventQueues.lookup("globalMessage", EventQueues.APPLICATION, true).publish(new Event("onSendMessage", null, message));
}
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
正如您所看到的,我将扩展AbstractVM
,但有1个部分非常重要然后只扩展它,即@Init
正如您所看到的,我再次声明了一个init方法,但我在注释中说的是superclass = true
如果我们不这样做,来自abstractVM的init方法将永远不会被触发
对于BasicComposer,这是不同的,如果覆盖doAfterCompose
方法,则始终调用super
,以便始终执行。
你可以在1台电脑上用多个会话进行测试,如下所示:
- 打开IE=>转到message.zul
- 在private中打开IE=>转到订阅了eventlistener的某个页面
- 私下打开FF=>与IE相同
- 在文本框中输入信息,然后按send
- 查看是否所有浏览器都收到消息。(如果您想确定,请将
String.valueOf(Sessions.getCurrent())
放在Clients.showNotification
中)
希望这能帮助你解决问题。
- 使用JSP从服务器检索和显示图像
- 如何使用skip参数使用angular ui引导进行服务器端分页
- 客户端服务器REST API captcha实现
- 正在将base64 jpeg从input-type=file上传到服务器
- Zkoss:如何通知用户会话超时或与服务器的连接丢失
- 不知道为什么我的服务器超时.
- 节点.js服务器在浏览器中超时,但 cURL 请求有效
- 如何为重定向或其他服务器上新打开的页面设置超时
- node.js HTTP服务器、请求和响应超时之间的区别
- 在javascript或服务器端处理会话超时
- Strophe.js客户端连接到服务器,断开连接/超时
- Node.js:服务器等待响应和超时
- 调用collection.find()会导致内部服务器错误并在之后超时
- 处理Datatables中的会话超时(使用服务器端数据源处理)
- 我在客户端和服务器端都实现了xdomain脚本,但在IE9中不断获得'超时等待iframe套接字'警告
- socket.io非活动客户端连接的服务器端超时
- CoffeeScript:使用 node-imap 向服务器进行身份验证时出现超时错误
- 从客户端设置和清除节点服务器上的超时
- 在PhoneGap窗口.location.assign()中连接到服务器超时
- 如何检测ajax请求上的php服务器超时