[英]redis subscriber can't work with redis publisher
我現在正在使用Java設計Redis發布/訂閱系統,但遇到了問題。 我將向您顯示詳細信息:
發布者在這里:
public class RedisMessagePublisher implements MessagePublisher {
public RedisMessagePublisher(StringRedisTemplate redisTemplate,ChannelTopic topic)
{
this.redisTemplate = redisTemplate;
this.topic = topic;
}
private StringRedisTemplate redisTemplate;
private ChannelTopic topic;
@Override
public void publish(String message) {
redisTemplate.convertAndSend(topic.getTopic(), message);
}
}
發布者是正確的並且可以正常工作。
然后我們轉到訂戶類:
public class RedisMessageSubscriber implements MessageListener {
//action inspect here
private Action2<Message, byte[]> action;
public void setAction(Action2<Message, byte[]> action) {
logger.info("action set");
this.action = action;
}
private static Logger logger = LogManager.getLogger(RedisMessageSubscriber.class);
@Override
public void onMessage(Message message, byte[] bytes) {
logger.info("===> redis subscribe message in <===");
if (action != null)
action.call(message, bytes);
else
logger.info("===> action is null <===");
}
}
在訂閱者類中,我使用RxJava注入了Action,以便可以更輕松地使用它。
但是問題出在這里,當我發布發布者的消息之后,我可以將消息轉移到onMessage方法中,日志打印不是我期望的:
===> redis subscribe message in <===
===> action is null <===
我期望的是,當我發布新消息時,訂閱者收到了該消息並運行了我創建的操作。
我用來觸發以下發布者和訂閱者的服務:
@RestController("redispubsubcontroller")
@RequestMapping(value = "/redis")
public class redispubsubcontroller {
@Autowired
private RedisMessagePublisher redisMessagePublisher;
@Autowired
private RedisMessageSubscriber redisMessageSubscriber;
private static Logger logger = LogManager.getLogger(redispubsubcontroller.class);
@RequestMapping(value = "/publisher", method = {RequestMethod.GET})
public ApiResponse getConfig(String message,HttpServletRequest request,
HttpServletResponse response) {
redisMessageSubscriber.setAction(new Action2<Message, byte[]>() {
@Override
public void call(Message message, byte[] bytes) {
ObjectMapper objectMapper = new ObjectMapper();
try {
String result = objectMapper.readValue(message.getBody(), String.class);
logger.info("receive:"+result);
} catch (IOException e) {
e.printStackTrace();
}
}
});
redisMessagePublisher.publish(message);
return new ApiResponse("success","message sent");
}
}
從上面的代碼中,您可以c我訂閱了該主題並為訂閱者設置了一個新操作:
redisMessageSubscriber.setAction(new Action2<Message, byte[]>() {
@Override
public void call(Message message, byte[] bytes) {
ObjectMapper objectMapper = new ObjectMapper();
try {
String result = objectMapper.readValue(message.getBody(), String.class);
logger.info("receive:"+result);
} catch (IOException e) {
e.printStackTrace();
}
}
});
但是我不知道為什么,在觸發發布者之后,訂閱者可以獲得消息但仍然保留NULL Action,而我創建的Action沒有傳遞給它。
有人可以幫忙嗎? 這個機制有問題嗎?
====編輯=====
RedisMessageConfig的代碼如下:
@Configuration
public class RedisMessageConfig {
@Bean
ChannelTopic topic() {
return new ChannelTopic("useraddresspubsub:queue");
}
@Bean
MessageListenerAdapter messageListener() {
return new MessageListenerAdapter(new RedisMessageSubscriber());
}
@Autowired
private RedisConnectionFactory JedisConnectionFactory;
@Bean
RedisMessageListenerContainer redisContainer() {
final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(JedisConnectionFactory);
container.addMessageListener(messageListener(), topic());
return container;
}
}
====解決====
最終,我按照mp的想法解決了這個問題,因為從redismessageconfig到redismessagesubscriber的流程從myismismagesubscriber更改為myredismessageconfig,所以在redismessageconfig中,我需要先向其注入操作,然后redismessageconfig將創建新的redismessagesubscriber並保留新創建的操作。 下面的代碼:
@Component
public class MyRedisMessageConfig extends RedisMessageConfig {
private static Logger logger =LogManager.getLogger(MyRedisMessageConfig.class);
public MyRedisMessageConfig() {
super.action = new Action2<Message, byte[]>() {
@Override
public void call(Message message, byte[] bytes) {
String result = new String(message.getBody());
logger.info("received:" + result);
}
};
}
}
這不是MessageListener
工作方式。 此外,您創建共享的可變狀態。 兩個並發調用會同時更改RedisMessageSubscriber
的狀態。
我假設您在一個線程中設置action
在另一個線程上發生消息接收時遇到了可見性問題。
如果每個MessageListener
要求不同的行為,則創建多個實現該行為的偵聽器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.