標籤:java redis spring
redis 訂閱發布
項目名稱:SmRemind_NEW
@Service
public class PubServiceImpl implements PubService {
@Resource(name="stringRedisTemplate")
private StringRedisTemplate stringRedisTemplate;
private String channelTopic = "Baojing";
/*發布訊息到Channel*/
public void Publisher(String message) {
stringRedisTemplate.convertAndSend(channelTopic, message);
}
}
sub端我使用的是java做服務(Spring)管理
項目名稱redis-service_pubsub
<!-- SDR Pub/Sub配置 -->
<bean id="topicMessageListener" class="com.chr.service.impl.SubServiceImpl">
</bean>
<bean id="topicMessageListener_stop" class="com.chr.service.impl.stopServiceImpl"></bean>
<bean id="topicContainer"
class="org.springframework.data.redis.listener.RedisMessageListenerContainer"
destroy-method="destroy">
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageListeners">
<map>
<entry key-ref="topicMessageListener">
<!-- <bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="user:topic" /> </bean> -->
<ref bean="channelTopic" />
</entry>
<entry key-ref="topicMessageListener_stop">
<!-- <bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="user:topic" /> </bean> -->
<ref bean="channelTopics" />
</entry>
</map>
</property>
</bean>
<bean id="channelTopic" class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="Baojing" />
</bean>
<bean id="channelTopics" class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="tuichu" />
</bean>
運行主類:
public class MainPcl {
public static Object o = new Object();
public static AtomicBoolean exit = new AtomicBoolean();
public static void main(String[] args) throws InterruptedException {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
RedisMessageListenerContainer r = (RedisMessageListenerContainer) context.getBean("topicContainer");
exit.set(true);
while (exit.get()) {
synchronized (o) {
o.wait();
};
}
r.stop();
}
}
寫無限迴圈,設定AtomicBoolean exit的值為true
AtomicBoolean 是線程保護的
當exit的值為false的時候終止迴圈
迴圈中調用object的wait()方法讓程式等待,因為wait()方法會在jdk不管什麼原因下異常退出,所以迴圈條件是exit的值為false
RedisMessageListenerContainer 為spring建立管理的pub/sub線程池
在迴圈結束的時候關閉線程池
因為object是靜態變數所以調用wait()方法時用synchronized
接收訊息類
public class SubServiceImpl implements SubService {
private Logger log = Logger.getLogger(this.getClass());
@Autowired
private ChannelTopic channelTopic;
@Autowired
private linkmanDao linkmanDao;
private String bjhm = "13201706118";
public void onMessage(Message message, byte[] pattern) {
//Message為接收訊息
// System.out.println(message.toString() + " 1111" + channelTopic.getTopic() + " " + Thread.currentThread().getName());
log.info("redis-service_pubsub|" + channelTopic.getTopic() + "|" + message);
//解析接收訊息;
String[] arg = message.toString().split("\\|");
//主叫號碼
String callingnum = arg[0];
//被叫號碼
String callednum = arg[1];
//時間
String calltime = arg[2];
if (callednum.equals(bjhm)) {
//被叫號碼等於配置號碼,查詢資料庫擷取傳送簡訊集合
//臨時使用My Phone號作為測試號碼
List<linkman> list = linkmanDao.getlinkman_Userid("13259781605");
for (linkman l : list) {
}
}
}
public String send(String smsUrl, String message, String phonenum) {
String sendurl = String.format(smsUrl, phonenum);
log.info("redis-service_pubsub|send|" + phonenum + "|success|url:" + sendurl + "|message:" + message);
// if (true) {
// return "ok";
// }
try {
URL url = new URL(sendurl);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setRequestProperty("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
httpCon.setRequestMethod("POST");
httpCon.setUseCaches(false);//POST方法設定成無緩衝
httpCon.setDoOutput(true);
httpCon.setConnectTimeout(5000);
httpCon.setReadTimeout(5000);
//POST方法將內容以流的方式寫出
OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream(), "utf-8");
out.write(message);
out.flush();
out.close();
//返回請求完成的狀態代碼
int httpcode = httpCon.getResponseCode();
if (httpcode == 204) {
return "ok";
} else {
return "exp";
}
} catch (Exception e) {
log.error("redis-service_pubsub|send|" + phonenum + "|error|url:" + sendurl + "|message:" + message, e);
return "exp";
}
}
暫停服務接收
public class stopServiceImpl implements SubService {
private Logger log = Logger.getLogger(this.getClass());
@Autowired
private ChannelTopic channelTopics;
public void onMessage(Message message, byte[] pattern) {
log.info("redis-service_pubsub|"+channelTopics.getTopic()+"|"+message);
//關閉服務
MainPcl.exit.set(false);
synchronized (MainPcl.o) {
o.notify();
};
}
}
兩個接收訊息類實際是一樣的,只是配置時
<bean id="channelTopic" class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="Baojing" />
</bean>
<bean id="channelTopics" class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="tuichu" />
</bean>
配置的channel的value不一樣。
redis pub/sub Spring StringRedisTemplate