package org.bigbluebutton.app.screenshare.messaging.redis;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Protocol;
public class MessageSender {
private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton");
private volatile boolean sendMessage = false;
private final Executor msgSenderExec = Executors.newSingleThreadExecutor();
private final Executor runExec = Executors.newSingleThreadExecutor();
private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>();
private JedisPool redisPool;
private String host;
private int port;
public void stop() {
sendMessage = false;
redisPool.destroy();
}
public void start() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(32);
config.setMaxIdle(8);
config.setMinIdle(1);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
config.setTestWhileIdle(true);
config.setNumTestsPerEvictionRun(12);
config.setMaxWaitMillis(5000);
config.setTimeBetweenEvictionRunsMillis(60000);
config.setBlockWhenExhausted(true);
// Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli
redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub");
log.info("Redis message publisher starting!");
try {
sendMessage = true;
Runnable messageSender = new Runnable() {
public void run() {
while (sendMessage) {
try {
MessageToSend msg = messages.take();
publish(msg.getChannel(), msg.getMessage());
} catch (InterruptedException e) {
log.warn("Failed to get message from queue.");
}
}
}
};
msgSenderExec.execute(messageSender);
} catch (Exception e) {
log.error("Error subscribing to channels: " + e.getMessage());
}
}
public void send(String channel, String message) {
MessageToSend msg = new MessageToSend(channel, message);
messages.add(msg);
}
private void publish(final String channel, final String message) {
Runnable task = new Runnable() {
public void run() {
Jedis jedis = redisPool.getResource();
try {
jedis.publish(channel, message);
} catch(Exception e){
log.warn("Cannot publish the message to redis", e);
} finally {
jedis.close();
}
}
};
runExec.execute(task);
}
public void setHost(String host){
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
}