我有一个发布订阅队列消息侦听器方法,当它在队列中读取消息时触发事件。将消息添加到ApplicationListener类中的publisherPostListenerList
。
列表中添加的消息正被推送到多个订阅者,例如来自控制器方法的实时通知。
将消息推送到相应的登录用户后,我将从列表中删除消息,以避免将冗余消息推送给用户,同时还会检查列表的大小。
问题是所有登录用户只有publisherPostListenerList
的单个实例。作为实例列表的列表应该为每个登录用户提供单独的副本,但事实并非如此。如果我错了,请纠正我。
如果我删除了一条消息,它会删除所有订阅者publisherPostListenerList
的消息。
现在我的问题是
1 即可。不应该为每个登录用户提供publisherPostListenerList列表的单独副本,该列表是实例列表。
2. 如何为所有已登录的用户创建单独的列表副本
P.S。我尝试将bean范围更改为原型但不起作用。
下面是ApplicationEventListener类,它包含列表和列表。控制器代码。
ApplicationListener.java
@Component
public class ApplicationEventListener {
private List<Post> publisherPostListenerList = new CopyOnWriteArrayList<Post>();
private static final Logger logger = Logger.getLogger(ApplicationEventListener.class);
@EventListener
public void postSubmissionEventHandler(PostSubmissionEvent event) throws IOException {
Post post = event.getPost();
logger.debug("application published user post received " + post);
publisherPostListenerList.add(post);
}
public List<Post> getPublisherPostListenerList() {
return publisherPostListenerList;
}
public void setPublisherPostListenerList(List<Post> publisherPostListenerList) {
this.publisherPostListenerList = publisherPostListenerList;
}
}
将消息推送给订阅者的控制器方法
@RequestMapping(value="/getRealTimeServerPushUserPosts")
public SseEmitter getRealTimeServerPushUserPosts(@RequestParam("userId") int userId){
SseEmitter sseEmitter = new SseEmitter();
CustomUserDetail myUserDetails = currentUserAccessor.getCurrentLoggedInUser();
User loggedInUser=myUserDetails.getUser();
List<Integer> userPublisherIDList = this.userService.loadUserPublisherIdListWhichLoggedInUserFollows(loggedInUser);
List<Post> postList =eventListener.getPublisherPostListenerList();
for(Integer userPublisherId : userPublisherIDList){
for(Post post:postList){
if((userPublisherId.intValue()) == (post.getUser().getUserId().intValue())){
try {
sseEmitter.send(post);
postList.remove(post); //removes the post for all the subscribers as the list acts as a global list.
} catch (IOException e) {
logger.error(e);
}
}
}
}
return sseEmitter;
}