Redis Jedis pub sub- How to implement pub/sub system using jedis library

1 month ago Lalit Bhagtani 0

In this tutorial, we will learn about how to implement redis pub sub system using Jedis library.

Jedis Library

Jedis is a Java client library for redis datastore. It is small and very easy to use, and fully compatible with redis 2.8.x, 3.x.x and above datastore. You can find here more information about jedis library.

Redis Pub/Sub System

Redis implements the Publish/Subscribe messaging paradigm. According to this messaging paradigm, the sender ( publisher ) of the message are not programmed to send their message directly to a specific receiver ( subscriber ). They send ( publish ) their message to a specific channel, without the knowledge of which or if any receiver will consume the message or not. A receiver, who wants to consume the message express their interest by subscribing to one or more channels, and they will receive the messages that are publish to those channels only, without the knowledge of which sender had send the message. You can find here more information about Redis Pub/Sub system.

Project Setup

Create a simple maven project in your favorite IDE and add below mentioned dependency in your pom.xml file.

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>3.0.1</version>
</dependency>

For latest version of jedis library, check this page.

Redis Installation

You will need to install latest version of Redis. Check this page for more information about installing redis.

Jedis Connection

Create an object of Jedis ( redis.clients.jedis.Jedis ) class for connecting your java code to redis.

Jedis jedis = new Jedis();

If you have started one redis service in your local machine and on default port (6379) then default constructor will just work fine. Otherwise you have to pass correct host url and port no. as an argument into the constructor.

Subscribe To Channels

Create a class “ChannelSubscribe”, this class will subscribe to channel C1 and C2 by creating a client. This client will receive a message, when any other client publish a message to channel C1 or channel C2.

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class ChannelSubscribe {

  public static void main(String[] args) {
		
    Jedis jedis = null;

    try {
			
	/* Creating Jedis object for connecting with redis server */
	jedis = new Jedis();
		
	/* Creating JedisPubSub object for subscribing with channels */	
	JedisPubSub jedisPubSub = new JedisPubSub() {
				
		@Override
		public void onMessage(String channel, String message) {
			System.out.println("Channel " + channel + " has sent a message : " + message );
			if(channel.equals("C1")) {
				/* Unsubscribe from channel C1 after first message is received. */	
				unsubscribe(channel);
			}
		}
				
		@Override
		public void onSubscribe(String channel, int subscribedChannels) {
			System.out.println("Client is Subscribed to channel : "+ channel);
			System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of channels");
		}
			
		@Override
		public void onUnsubscribe(String channel, int subscribedChannels) {
			System.out.println("Client is Unsubscribed from channel : "+ channel);
			System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of channels");
		}
			
	};
			
	/* Subscribing to channel C1 and C2 */
	jedis.subscribe(jedisPubSub, "C1", "C2");
			
	} catch(Exception ex) {			
			
		System.out.println("Exception : " + ex.getMessage());	
			
	} finally {
			
		if(jedis != null) {
			jedis.close();
		}
	}		
  }
}

Output

When you run a class “ChannelSubscribe”, output will be the following :- 

Jedis Pub Sub




Publish To Channels

Create a class “ChannelPublish”, this class will connect to redis server using jedis connection and will publish two messages each to channel C1 and C2.

import redis.clients.jedis.Jedis;

public class ChannelPublish {

  public static void main(String[] args) {
		
    Jedis jedis = null;
		
    try {			
        /* Creating Jedis object for connecting with redis server */
        jedis = new Jedis();
			
        /* Publishing message to channel C1 */
        jedis.publish("C1", "First message to channel C1");
			
        /* Publishing message to channel C2 */
        jedis.publish("C2", "First message to channel C2");
		
        /* Publishing message to channel C1 */
        jedis.publish("C1", "Second message to channel C1");
			
        /* Publishing message to channel C2 */
        jedis.publish("C2", "Second message to channel C2");
		
    } catch(Exception ex) {			
			
        System.out.println("Exception : " + ex.getMessage());
    } finally {
			
        if(jedis != null) {
          jedis.close();
        }		
    }
  }
}

Output

When you run a class “ChannelPublish”, output in the ChannelSubscribe console will be the following :- 

Jedis Pub Sub

Subscribe To Patterns

Create a class “PatternSubscribe”, this class will subscribe to pattern C* and D? by creating a client.

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class PatternSubscribe {

  public static void main(String[] args) {
		
	Jedis jedis = null;
	
	try {
			
	/* Creating Jedis object for connecting with redis server */
	jedis = new Jedis();
			
	/* Creating JedisPubSub object for subscribing with channels */	
	JedisPubSub jedisPubSub = new JedisPubSub() {
				
		@Override
		public void onPMessage(String pattern, String channel, String message) {
			System.out.println("Channel " +channel+ " has sent a message : " +message+ " on pattern " + pattern);
			if(pattern.equals("C*")) {
				/* Unsubscribe from pattern C* after first message is received. */	
				punsubscribe(pattern);
			}
		}
				
		@Override
		public void onPSubscribe(String pattern, int subscribedChannels) {
			System.out.println("Client is Subscribed to pattern : "+ pattern);
			System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of patterns");
		}
				
		@Override
		public void onPUnsubscribe(String pattern, int subscribedChannels) {
			System.out.println("Client is Unsubscribed from pattern : "+ pattern);
			System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of patterns");
		}
				
	};
			
	/* Subscribing to channel C1 and C2 */
	jedis.psubscribe(jedisPubSub, "C*", "D?");
			
	} catch(Exception ex) {			
			
		System.out.println("Exception : " + ex.getMessage());	
			
	} finally {
		
		if(jedis != null) {
			jedis.close();
		}
		
	}		
  }

}

Output

When you run a class “PatternSubscribe”, output will be the following :- 

Jedis Pub Sub

Publish To Patterns

Create a class “PatternPublish”, this class will connect to redis server using jedis connection and will publish messages to channel C13, D2, C134, and D3.

import redis.clients.jedis.Jedis;

public class PatternPublish {

  public static void main(String[] args) {
	
	Jedis jedis = null;
	
	try {			
	/* Creating Jedis object for connecting with redis server */
	jedis = new Jedis();
			
	/* Publishing message to channel C13 */
	jedis.publish("C13", "Message to channel C13");
	
	/* Publishing message to channel D2 */
	jedis.publish("D2", "Message to channel D2");
		
	/* Publishing message to channel C134 */
	jedis.publish("C134", "Message to channel C134");
			
	/* Publishing message to channel D3 */
	jedis.publish("D3", "Message to channel D3");
			
	} catch(Exception ex) {			
			
        	System.out.println("Exception : " + ex.getMessage());	
			
	} finally {
			
		if(jedis != null) {
			jedis.close();
		}
			
	}
  }
	
}

Output

When you run a class “PatternPublish”, output in the PatternSubscribe console will be the following :-

Jedis Pub Sub

References :-

  1. Pub Sub Command Docs

That’s all for how to implement redis pub sub system using Jedis library. If you liked it, please share your thoughts in comments section and share it with others too.