我在CometD服务器上有一个SessionListener。我想在调用侦听器的sessionAdded()方法时将数据从客户端传递到服务器。

sessionAdded()方法接收一个ServerSession和ServerMessage对象。 ServerSession具有一个属性映射,该属性映射似乎始终没有任何内容。

我想获取一些唯一的客户端数据到服务器。调用sessionAdded()方法时,服务器应访问此数据。

该文档讨论了SessionListener的基本用法,但未提及任何属性。客户机和服务器的所有Javadocs都说这是描述setAttribute()如何设置属性以及getAttribute()如何获取它。

有没有办法做到这一点? ServerSession的属性映射可以用于将属性从客户端传输到服务器吗?如果可以,如何?

有人请指教...

最佳答案

ServerSession属性映射是驻留在服务器上的映射。

它是不透明的(从CometD的角度来看)地图,应用程序可以根据需要填充这些地图。

如果要将数据从客户端发送到服务器,可以将这些附加数据放入握手消息中,然后在调用BayeuxServer.SessionListener.sessionAdded()时从消息中检索它。

客户看起来像这样:

BayeuxClient client = ...;
Map<String, Object> extraFields = new HashMap<>();
Map<String, Object> ext = new HashMap<>();
extraFields.put(Message.EXT_FIELD, ext);
Map<String, Object> extraData = new HashMap<>();
ext.put("com.acme", extraData);
client.handshake(extraFields);
extraData.put("token", "foobar");


这将创建一个额外的数据结构,该数据结构在JSON中如下所示:

{
  "ext": {
    "com.acme": {
      "token": "foobar"
    }
  }
}


将数据放在com.acme之类的命名空间下始终是一个很好的做法,这样就不会弄乱CometD字段或可能使用的其他扩展名。
将您的字段放在extraData内,例如上例中的字段token

然后,在服务器上:

public class MySessionListener implements BayeuxServer.SessionListener {
  @Override
  public void sessionAdded(ServerSession session, ServerMessage message) {
    Map<String, Object> ext = message.getExt();
    if (ext != null) {
      Map<String, Object> extra = (Map<String, Object>)ext.get("com.acme");
      if (extra != null) {
        String token = (String)extra.get("token");
        session.setAttribute("token", token);
      }
    }
  }

  @Override
  public void sessionRemoved(ServerSession session, boolean timedout) {
  }
}


token字段上方的示例中,此侦听器将客户端发送的会话属性数据放入其中。

然后,在应用程序的其他位置,您可以访问会话属性并使用该数据。

07-27 19:11