简体   繁体   English

具有Hazelcast会话复制的自定义会话侦听器

[英]Custom session Listener with Hazelcast session replication

I have Hazelcast configured for session replication: 我为会话复制配置了Hazelcast:

<filter>
  <filter-name>hazelcast-filter</filter-name>
  <filter-class>com.hazelcast.web.WebFilter</filter-class>

  <init-param>
    <param-name>map-name</param-name>
    <param-value>my-sessions</param-value>
  </init-param>
  <init-param>
    <param-name>cookie-name</param-name>
    <param-value>hazelcast.sessionId</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>hazelcast-filter</filter-name>
  <url-pattern>/</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<listener>
  <listener-class>com.hazelcast.web.SessionListener</listener-class>
</listener>

In my web application user can make Order which persists in session until it's finished. 在我的Web应用程序中,用户可以使Order保留在会话中直到完成。 In case Order was not finished and session was destroyed (user logged out or session expired), I want to backup all data that was processed by that order. 如果订单未完成且会话被破坏(用户注销或会话过期),我想备份该订单处理的所有数据。

Without Hz session replication, I accomplish this with custom HttpSessionListener implementation like: 如果没有Hz会话复制,我将通过自定义HttpSessionListener实现来实现,例如:

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    Order order = (Order) se.getSession().getAttribute("order");
    if (order != null) {
      // Backup all data processed by order
    }
}

and it works fine, but with Hz I get 2 different sessions which are not synced: 它可以正常工作,但是在Hz下,我得到了2个未同步的会话:

switch (action) {
    case "addOrderItems":
        System.out.print("sesId=" + req.getSession().getId());
        System.out.println("order=" + req.getSession().getAttribute("order"));

prints sesId=HZDCDC1C77E7934E03A9FE329AAB7053B0 order=Order@6a5f7445 打印sesId=HZDCDC1C77E7934E03A9FE329AAB7053B0 order=Order@6a5f7445

while

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    System.out.print("sesId=" + se.getSession().getId());
    System.out.println("order=" + se.getSession().getAttribute("order"));

prints sesId=8748D170885C44B425FEEAA94AAB8A86 order=null . 打印sesId=8748D170885C44B425FEEAA94AAB8A86 order=null

It seems that Hazelcast creates and destroys it's own session and I can't (or don't know how to) listen on this session events. Hazelcast似乎创建并销毁了它自己的会话,而我不能(或不知道如何)监听此会话事件。

Is it possible to keep both sessions in sync or to implement your own Listener for Hz session? 是否可以使两个会话保持同步或为Hz会话实现您自己的侦听器?

Two steps should get you there 两步就可以到达你

If you create a Hazelcast instance first, then you can pass the name of that as a parameter, 如果您首先创建Hazelcast实例,则可以将其名称作为参数传递,

<init-param>
  <param-name>instance-name</param-name>
  <param-value>whatever</param-value>
</init-param>

so then session replication will use that pre-existing Hazelcast instance rather than spawn a new one. 因此,会话复制将使用该预先存在的Hazelcast实例,而不是生成一个新实例。

When you create that instance, you can attach a listener to the session storage map in the normal way. 创建该实例时,可以按常规方式将侦听器附加到会话存储映射。

<map name="my-sessions">
  <entry-listeners>
    <entry-listener local="true" include-value="true">your.entry.Listener</entry-listener>
  </entry-listeners>
</map>

As Neil Stevenson mentioned, Hazelcast instance should be preconfigured with EntryListener for my-sessions map. 正如尼尔·史蒂文森(Neil Stevenson)所提到的,应该为my-sessions映射使用EntryListener预配置Hazelcast实例。 With filter for session replication as in my case, I added 与我的情况一样,使用用于会话复制的过滤器,我添加了

<map name="my-sessions">
  <entry-listeners>
    <entry-listener local="true" include-value="true">path.to.NewOrderSessionListener</entry-listener>
    </entry-listeners>
</map>

to hazelcast.xml (which is located in the right place ). hazelcast.xml (位于正确的位置 )。

Implementation of EntryRemovedListener<String, SessionState> to listen for Hz session delete event will be like 实现EntryRemovedListener<String, SessionState>来监听Hz会话删除事件将像

public class NewOrderSessionListener implements EntryRemovedListener<String, SessionState> {
  @Override
  public void entryRemoved(EntryEvent<String, SessionState> event) {
    SessionState state = event.getOldValue();
    Map<String, Data> map = state.getAttributes();
    Data orderData = map.get("order");
    if (orderData != null) {
      // Backup all data processed by order
    }

Actually, Hazelcast provides a solution for any event. 实际上,Hazelcast 为任何事件提供解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM