【问题标题】:Wicket - Inter-session communication or Create new Request(Cycle) manuallyWicket - 会话间通信或手动创建新请求(周期)
【发布时间】:2013-06-29 12:02:40
【问题描述】:

我有一些检票口面板存储在来自不同会话的静态哈希图中,我想做一些事情,比如如果某个面板通知地图,然后地图通知所有其他面板。 例如:

public class PanelMap{
    private static Map<Long, List<MyPanel>> map = new HashMap<Long, List<MyPanel>>();

public static void subscribe(Long id, MyPanel panel){
        if (!map.containsKey(id)){
            map.put(id, new ArrayList<MyPanel>());
        }
        map.get(id).add(panel);
    }
}

public static void notify(Long id, String notification){
        if (map.containsKey(id)){
            List<MyPanel> panels = map.get(id);
            for(MyPanel panel : panels){
                panel.newNotification(notification);
            }
        }
    }
}

在面板中,newNotification(字符串通知)我想向服务器发送请求并在浏览器中刷新我的面板。

public void String newNotification(String notification){
   // do some business logic depends on notification
   onMyRequest();
}

我在检票口行为源文件中进行了一些搜索,并在AbstractDefaultAjaxBehavior 中找到了关于我尝试在检票口面板中创建自己的 onRequest 方法,如下所示

private void onMyRequest(){
    AjaxRequestTarget target = ((WebApplication)getApplication()).newAjaxRequestTarget(getPage());
        target.add( _some_wicket_components_ );

        RequestCycle.get().scheduleRequestHandlerAfterCurrent(target);
    }

但我所做的只是 Wicket Ajax Debug 中的一些 Ajax 错误

 Wicket.Ajax.Call.processComponent: Component with id _containerdiv_ was not found while trying to perform markup update.
ERROR: Cannot find element with id: _someComponentIdOnPanel_

(那些组件是存在的)

如何向服务器发送我自己的请求(或者如何获得有效的 AjaxRequestTarget 来更新我的组件?)

更新:我需要会话间通信。

【问题讨论】:

  • in html 页面中是否存在_some_wicket_components_
  • 是的,确实如此,它基本上是一个 WebMarkupContainer,内容容器 (
    )
  • 您是否有理由不使用检票口事件总线?
  • 唯一的原因是我不知道它是什么:) 它是干什么用的?一些主要,指南或链接?请
  • 您能否详细说明“会话间通信”的含义?我的会话影响了另一个用户的会话,或者我的会话影响了我的另一个会话(我如何以及为什么会获得多个会话?)?显然,您不能将其他用户面板添加到我的 AjaxRequestTarget。为此,您需要某种推送技术,例如 Atmosphere,或者您必须等到其他用户创建自己的 AjaxRequestTarget(可能使用 TimedUpdatingBehaviour。

标签: request wicket


【解决方案1】:

要在不同用户的会话上更新面板,显然不能使用当前的 AjaxRequestTarget,因为这在某种程度上代表了服务器与另一个用户的浏览器无法知道的请求用户之间的单一通信。 (非常非常基本的口语)

您可以使用an AjaxSelfUpdatingTimerBehavior 来轮询更新。这将定期为每个用户生成新的 AjaxRequestTarget,您可以使用它来附加更改的面板。这是一个非常基本且简单的实现,很可能会影响您的系统性能并产生相当多的流量。

另一种方法是使用 Atmosphere 之类的东西,它由 Wicket-Atmosphere 支持(可以在 here 找到快速入门)并且在 wicket-library.com 上有一些示例,但这就是我所知道的全部.

【讨论】:

  • 我不想使用 AjaxSelfUpdatingTimerBehavior,但是 wicket Atmosphere 听起来不错。老实说,三天时间试图恢复一个简单的“hello-world”示例。我无法配置 web.xml 和大气.xml 但我仍在战斗
  • @Victor 听起来不太好,但我对 Atmosphere 的了解只是我在检票口变更日志上看到的。也许这本身就需要一个新问题。
【解决方案2】:

使用 Wicket 事件总线系统。查看free Wicket guide 的“Wicket 事件基础设施”一章。

首先,您需要创建一个类来封装通知和AjaxRequestTarget,并使用事件基础结构传递它们。

private class Notification {
    private String message;
    private AjaxRequestTarget target;

    ... constructor, getters, setters...
}

然后想要接收事件的面板必须覆盖onEvent 方法,如下所示:

public void onEvent(IEvent<?> event) {
    if (event.getPayload() instanceof Notification) {
        Notification notification = (Notification) event.getPayload();

        ... do whatever you want before updating the panel ...

        // Update the panel 
        notification.getTarget().add(this);

    }
}

所有组件都将接收使用 Wicket 事件基础架构发送的所有事件。因此,您可以使用这样的一种方法从任何其他面板发送事件

protected void sendMessage(String message, AjaxRequestTarget target) {
    send(getSession(), Broadcast.BREADTH, new Notification(message, target));
}

请记住,如果要使用 AJAX 更新组件,则需要设置 setOutputMarkupId(true)。而如果它是一个可以隐藏的组件,并且你想使用 AJAX 使其可见,那么你需要设置setOutputMarkupPlaceholderTag(true)

【讨论】:

  • 好的,然后使用 Session 作为 IEventSink 而不是 getPage()。我要更新 sendMessage 方法。
  • 听起来不错,我会在 18:00 CEST UTC/GMT +2 左右到家后检查一下
  • 您是指不同用户的会话吗?如果是这样,那么我误解了,下面的答案是好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
  • 2012-01-26
  • 2012-11-30
  • 2015-05-18
  • 2021-06-15
  • 1970-01-01
相关资源
最近更新 更多