问题描述
具有订阅者类别:
import org.apache.log4j.LogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
public class Subscriber extends JedisPubSub {
private static final org.apache.log4j.Logger logger = LogManager.getLogger(Subscriber.class);
@Override
public void onMessage(String channel,String message) {
logger.info("Message received. Channel: " + channel + ",Msg: " + message);
}
@Override
public void onSubscribe(String channel,int subscribedChannels) {
logger.info("Subscribed to channel: " + channel);
}
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
JedisSentinelPool pool = new JedisSentinelPool(masterName,sentinelsHashSet,password);
Jedis jPublisher = pool.getResource();
Jedis jedis = pool.getResource();
Subscriber subscriber = new Subscriber();
jedis.subscribe(subscriber,channel);
jedis.quit();
} catch (Exception e) {
logger.error(e.toString());
}
}
});
t.run();
}
}
我基本上想打印在Redis通道上收到的所有消息,我想用不同的onMessage或onSubscribe方法创建子类。我从Main class调用订户类
Subscriber sb = new Subscriber();
sb.main(new String[]{});
所以我尝试了:
- 复制main方法并将
Subscriber subscriber = new Subscriber();
更改为SubscriberExtended subscriber = new SubscriberExtended();
并通过以下方式从Main
类进行调用: 1.1)
Subscriber sb = new SubscriberExtended();
sb.main(new String[]{});
或
SubscriberExtended sb = new SubscriberExtended();
sb.main(new String[]{});
import org.apache.log4j.LogManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
public class SubscriberExtended extends Subscriber {
private static final org.apache.log4j.Logger logger = LogManager.getLogger(SubscriberExtended.class);
@Override
public void onSubscribe(String channel,int subscribedChannels) {
logger.info("Subscribed to channel from Extended class: " + channel);
}
public SubscriberExtended() {
}
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
JedisSentinelPool pool = new JedisSentinelPool(masterName,password);
Jedis jPublisher = pool.getResource();
Jedis jedis = pool.getResource();
SubscriberExtended subscriber = new SubscriberExtended();
jedis.subscribe(subscriber,channel);
jedis.quit();
} catch (Exception e) {
logger.error(e.toString());
}
}
});
t.run();
}
- 我也尝试过使用构造函数
public SubscriberExtended() {
super.main(new String[]{});
}
其他配置几乎没有任何效果。 我要实现的目标是创建SubscriberExtended类,该类的行为与Subscriber类相同,但重写onMessage或onSubscribe方法。谁能帮我吗?
解决方法
这似乎应该起作用,尽管我不确定为什么要向所有类添加静态主体。 您应该能够执行以下操作:
public class Subscriber extends JedisPubSub {
private static final org.apache.log4j.Logger logger = LogManager.getLogger(Subscriber.class);
@Override
public void onMessage(String channel,String message) {
logger.info("Message received. Channel: "+channel+",Msg: "+message);
}
@Override
public void onSubscribe(String channel,int subscribedChannels) {
logger.info("Subscribed to channel: " + channel);
}
public void start() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
JedisSentinelPool pool = new JedisSentinelPool(masterName,sentinelsHashSet,password);
Jedis jedis = pool.getResource();
jedis.subscribe(this,channel);
jedis.quit();
} catch (Exception e) {
logger.error(e.toString());
}
}
});
t.start();
}
}
public class SubscriberExtended extends Subscriber {
@Override
public void onMessage(String channel,String message) {
logger.info("Extended Message received. Channel: "+channel+",Msg: "+message);
}
}
然后,从主要功能的某个地方,您将获得以下内容:
public class Main()
{
public static void main(String[] args)
{
SubscriberExtended se = new SubscriberExtended();
se.start();
while(true) {
// do something else or sleep
}
}
}
我相信您犯的一个错误是调用t.run()而不是t.start()。 t.run()将不会返回,除非订阅由于某种原因而失败,例如与REDIS的连接已关闭。 t.start()将启动线程。
您似乎也无缘无故地从jedis池中获取发布者连接。
另一个问题在这里:
Subscriber sb = new SubscriberExtended();
sb.main(new String[]{});
sb.main
还将继续调用new SubscriberExtended()
与订阅一起使用,因此您的sb
对象将不会收到任何发布-它们将转到在sb.main中创建的实例代替。在start()
方法中使用“ this”进行订阅将解决该问题。
设置完成后,您可以继续使用redis-cli连接到REDIS,然后发布以查看您的程序是否收到该消息。