获取SpringWebSocket消息的调度方法中的主体

获取SpringWebSocket消息的调度方法中的主体,spring,websocket,stomp,spring-websocket,spring-messaging,Spring,Websocket,Stomp,Spring Websocket,Spring Messaging,要使用WebSocket向特定客户端发送通知。具有用于发送通知的计划任务,但无法在该任务内获取主体。找到了post,但正如我所知,Spring调度方法必须是无参数的 @Scheduled(fixedDelay=5000) public void sendMessages(Principal principal) messagingTemplate .convertAndSendToUser(principal.getName(), "/queue/horray", "Horray, "

要使用WebSocket向特定客户端发送通知。具有用于发送通知的计划任务,但无法在该任务内获取主体。找到了post,但正如我所知,Spring调度方法必须是无参数的

@Scheduled(fixedDelay=5000)
public void sendMessages(Principal principal)
messagingTemplate
    .convertAndSendToUser(principal.getName(), "/queue/horray", "Horray, " + principal.getName() + "!");
}

这可能吗?如何在计划的方法中获取websocket主体?

您无法在计划的方法中获取主体,因为方法调用不是由用户发起的

您可以遵循以下方法:

1) 创建websocket端点“/app/events”

2) 让所有用户订阅该端点

3) 获取要发送通知的所有用户标识

4) 向单个用户发送通知

simpMessagingTemplate.convertAndSendToUser("userId", "/app/events", "messageEntity"); 

userId: can be actual user id if authenticated or it can be websocket session id.

我为这种情况写了一个变通办法。首先,我为websockets事件创建一个侦听器。在订阅请求的情况下,我保留请求中的用户ID并保存在ConcurrentHashMap中。另一方面,当客户端断开连接或发送取消订阅请求时,我会从映射中删除他的用户ID

我的侦听器类:

@Service
public class MyEventListener {

  @Autowired
  private NotificationPublisher notificationPublisher;

  @EventListener({SessionSubscribeEvent.class})
  public void onWebSocketSubscribeEvent(SessionSubscribeEvent event) {
      notificationPublisher.subscribedUsers.put(event.getUser().getName(), Calendar.getInstance().getTimeInMillis());
  }

  @EventListener({SessionUnsubscribeEvent.class})
  public void onWebSocketUnsubscribeEvent(SessionUnsubscribeEvent event) {
      notificationPublisher.subscribedUsers.remove(event.getUser().getName());
  }

  @EventListener({SessionDisconnectEvent.class})
  public void onWebSocketDisconnectEvent(SessionDisconnectEvent event) {
      notificationPublisher.subscribedUsers.remove(event.getUser().getName());
  }
}
实际作业正在运行的通知发布者类:

public class NotificationPublisher {
  public final Map<String, Long> subscribedUsers = new ConcurrentHashMap<>();

  @Autowired
  private SimpMessagingTemplate messagingTemplate;

  @Autowired
  private MyService myService;

  @Value("${task.notifications.publisher.websocket_timeout_seconds}")
  private int websocketSessionTimeout;

  public void sendDataUpdates() {
    SocketResponseCount count = null;

    for(String key: subscribedUsers.keySet()) {
        long subscribeTime = subscribedUsers.get(key);

        if(Calendar.getInstance().getTimeInMillis() - subscribeTime > websocketSessionTimeout*1000) {
            subscribedUsers.remove(key);
            continue;
        }

        count = myService.getNotificationsCount(key);
        this.messagingTemplate.convertAndSendToUser(key, "/queue/publish",count);
    }
  }
}
公共类NotificationPublisher{
public final Map subscribedUsers=新的ConcurrentHashMap();
@自动连线
私有SimpMessagingTemplate消息模板;
@自动连线
私人MyService-MyService;
@值(${task.notifications.publisher.websocket\u timeout\u seconds}”)
私有int websocketSessionTimeout;
public void sendDataUpdates(){
SocketResponseCount计数=null;
for(字符串键:subscribedUsers.keySet()){
long subscribedtime=subscribedUsers.get(key);
if(Calendar.getInstance().getTimeInMillis()-subscribeTime>websocketSessionTimeout*1000){
订阅用户。删除(键);
继续;
}
count=myService.getNotificationsCount(键);
此.messagingTemplate.convertAndSendToUser(键“/queue/publish”,count);
}
}
}

也许它会帮助某人

我的解决方案:我获得所有用户会话

@Autowired
private SimpMessagingTemplate template;
@Autowired
private MyRepository myRepository;
@Autowired
private SessionRegistry sessionRegistry;



@Scheduled(fixedRate = 5000)
public void greeting() {

    List<SessionInformation> activeSessions = new ArrayList<>();

    for (Object principal : sessionRegistry.getAllPrincipals() )
    {
        activeSessions.addAll( sessionRegistry.getAllSessions( principal, false ) );
    }
    for (SessionInformation session : activeSessions )
    {
        Object principalObj = session.getPrincipal();
        if ( principalObj instanceof CurrentUser)
        {
            CurrentUser user = (CurrentUser) principalObj;
            this.template.convertAndSendToUser(user.getUsername().toUpperCase(),"/queue/reply2",myRepository.findAll());

        }

    }
}
@Autowired
私有SimpMessagingTemplate;
@自动连线
私有MyRepository MyRepository;
@自动连线
非公开会议登记处会议登记处;
@计划(固定利率=5000)
公众问候语(){
List activeSessions=new ArrayList();
对于(对象主体:sessionRegistry.GetAllPrinciples())
{
addAll(sessionRegistry.getAllSessions(主体,false));
}
用于(会话信息会话:activeSessions)
{
Object principalObj=session.getPrincipal();
if(当前用户的principalObj实例)
{
CurrentUser=(CurrentUser)principalObj;
this.template.convertAndSendToUser(user.getUsername().toUpperCase(),“/queue/reply2”,myRepository.findAll());
}
}
}