Use Redis's pub/sub to implement message persistence similar to JMS

Source: Internet
Author: User
Tags auth message queue redis stub unique id

The understanding of individual pub/sub mechanisms provided by Redis is covered in the previous blog, as well as the idea of how to avoid one of the biggest flaws in Redis pub/sub-The persistence of messages (http://blog.csdn.net/canot/ article/details/51975566). This article is mainly about the code implementation of its idea (Redis pub/sub message persistence):

The realization of the core listener in the PUB/SUB mechanism:

Import Redis.clients.jedis.Jedis;
Import Redis.clients.jedis.JedisPubSub;

Import Redis.clients.util.RedisInputStream;
    public class Pubsublistener extends Jedispubsub {private String clientId;

    Private Handlerredis Handlerredis; When generating Pubsublistener, you must develop an ID public pubsublistener (String cliendid, Jedis jedis) {This.clientid = Cliendid
        ;
        Jedis.auth ("xxxx");
    Handlerredis = new Handlerredis (Jedis);
            @Override public void OnMessage (string channel, String message) {if (' Quit '. Equals (message)) {
        This.unsubscribe (channel);
    } handlerredis.handler (channel, message); ///Real handle accepted place private void message (string channel, String message) {SYSTEM.OUT.PRINTLN ("message receive
    : "+ message +", Channel: "+ Channel +" ... "); @Override public void Onpmessage (string pattern, string channel, String message) {//TODO Auto-generat Ed method stub} @Override public void Onsubscribe (String channel, int subscribedchannels) {//Save subscriber in a subscription active collection HANDLERREDIS.SUBSC
        Ribe (channel);
    SYSTEM.OUT.PRINTLN ("Subscribe:" + channel); @Override public void Onunsubscribe (String channel, int subscribedchannels) {Handlerredis.ubsubscribe (
        Channel);
    System.out.println ("Unsubscribe:" + channel); @Override public void Onpunsubscribe (String pattern, int subscribedchannels) {//TODO auto-generated m Ethod stub} @Override public void Onpsubscribe (String pattern, int subscribedchannels) {//TODO Au

        to-generated method Stub} class Handlerredis {private Jedis Jedis;
        Public Handlerredis (Jedis jedis) {This.jedis = Jedis;
            public void handler (string channel, String message) {int index = Message.indexof ("/");
       if (Index < 0) {//Message not valid, discard return;     Long Txid = long.valueof (message.substring (0, index));
            String key = ClientId + "/" + channel;
                    while (true) {String LM = Jedis.lindex (key, 0);//Get the first message if (LM = = null) {
                Break
                int li = Lm.indexof ("/");
                    If the message is not valid, delete and process if (Li < 0) {String result = Jedis.lpop (key);//delete current messages
                    is an empty if (result = = null) {break;
                    } message (channel, LM);
                Continue
                Long Lxid = long.valueof (lm.substring (0, Li))//Get message's TXID//Direct consumption TXID before the residue message
                    if (Txid >= lxid) {jedis.lpop (key);//delete the current message message (channel, LM);
                Continue } else {break;
                }}//persistent subscription operation public void subscribe (String channel) {
            guarantee that the format in the Subscriber collection is a unique identifier/subscribed channel String key = ClientId + "/" + channel;
            Determines whether the client exists in the collection Boolean isexist = Jedis.sismember ("Persis_sub", key);
            if (!isexist) {//does not exist then add Jedis.sadd ("Persis_sub", key);
            } public void Ubsubscribe (String channel) {string key = ClientId + '/' + channel;
            Jedis.srem from the "Active Subscriber" collection ("Persis_sub", key);
        Delete Subscriber Message Queuing Jedis.del (channel);
 }
    }
}

An internal class Handlerredis is defined in the listener. The Listener class delivers onmessage and Onsubscribe two methods to Handlerredis. Handler process This method is also the maintenance of the queue. The Listener class defines a message () method, which is the handler callback method, which is where the messages are actually processed.

Subscription client class for channel:

Import Redis.clients.jedis.Jedis;

public class Subclient {
   private Jedis Jedis;
   Private Pubsublistener listener;

   Public subclient (String Host,pubsublistener pubsublistener) {
       Jedis = new Jedis (host);
       Jedis.auth ("XXXXX");
       This.listener = Pubsublistener;
   }

   public void Sub (String channel) {
        jedis.subscribe (listener, channel);
    }

    public void Unsubscribe (String channel) {
        listener.unsubscribe (channel);
    }

}

The client of the channel's message publishing:

Import Java.util.Set;

Import Redis.clients.jedis.Jedis;

    public class Pubclient {private Jedis Jedis;
        Public pubclient (String host) {Jedis = new Jedis (host);
    Jedis.auth ("wx950709");
        /** * Every message that is published needs to be persisted in the Subscriber message Queue * * @param messages/public void put (String message) {
        Get all active message recipient client Clientid/channel set<string> subclients = jedis.smembers ("Persis_sub");
        for (String subs:subclients) {//Save messages for each client Jedis.rpush (subs, message); } public void Publish (string channel, String message) {//per messages, all with a globally unique ID//TXID to prevent subscriber end in data
        Processing "disorderly", which requires subscribers need to parse the message Long Txid = JEDIS.INCR ("Message_txid");
        String content = Txid + "/" + message;
        This.put (content);
        Jedis.publish (channel, content)//set ID for each message, final message format 1000/messagecontent} public void Close (String channel) {
      Jedis.publish (channel, "Quit");  Jedis.del (channel);//Delete}}
 

To test the boot class:

Import Redis.clients.jedis.Jedis;

public class Main {public
    static void Main (string[] args) throws exception{
        pubclient pubclient = new Pubclient (" 127.0.0.1 ");
        Final String channel = "pubsub-channel222";
        Pubsublistener listener = new Pubsublistener ("Client_one", New Jedis ("127.0.0.1"));
        Subclient subclient = new subclient ("127.0.0.1", listener);
        thread T1 = new Thread (new Runnable () {

            @Override public
            void Run () {
                //At API level, where polling is done, until unsubscribe call, to return
                subclient.sub (channel); 
            }

        );
        T1.setdaemon (true);
        T1.start ();

        int i = 0;
        while (I < 2) {
            pubclient.publish (channel, "message" +i);
            i++;
            Thread.Sleep (1000);}}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.