如何通过轮询检索新的传入数据并将其反馈

时间:2013-01-09 15:26:04

标签: java oop object methods long-polling

这里的方法读取具有唯一ID的数据库,其序列号不断增加,因为我是java的初学者,我是否可以知道如何实现这种重复轮询并每次检查新的传入消息。

public void run() {
int seqId = 0;
    while(true) {
        List<KpiMessage> list = null;
        try {
            list = fullPoll(seqId);
            if (!list.isEmpty()) {
                seqId = list.get(0).getSequence();
                incomingMessages.addAll(list);
                System.out.println("waiting 3 seconds");
                System.out.println("new incoming message");
                Thread.sleep(3000);

            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }


    }
}

//Method which defines polling of the database and also count the number of Queries
public List<KpiMessage> fullPoll(int lastSeq) throws Exception {
    Statement st = dbConnection.createStatement();
    ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION =  804 and SEQ >" + lastSeq + "order by SEQ DESC");     
    List<KpiMessage> pojoCol = new ArrayList<KpiMessage>();
    while (rs.next()) {
        KpiMessage filedClass = convertRecordsetToPojo(rs);
        pojoCol.add(filedClass);
    }
    for (KpiMessage pojoClass : pojoCol) {
        System.out.print(" " + pojoClass.getSequence());
        System.out.print(" " + pojoClass.getTableName());
        System.out.print(" " + pojoClass.getAction());
        System.out.print(" " + pojoClass.getKeyInfo1());
        System.out.print(" " + pojoClass.getKeyInfo2());
        System.out.println(" " + pojoClass.getEntryTime());
    }
    //          return seqId;           
    return pojoCol;
}  

我的目标是从数据库中轮询表并检查新的传入消息,我可以从表中的Header字段SequenceID中找到该消息,该消息是唯一的并且对于新条目不断增加。现在我的问题是

1.让我们说,在我第一次轮询之后,它会读取所有条目并让线程休眠6秒,平均时间如何获取新的传入数据并再次轮询?

2.如何添加新数据,当它第二次进行轮询并将新数据传递给另一个类时。

2 个答案:

答案 0 :(得分:2)

Poller每6秒调用一次fullPoll并将lastSeq参数传递给它。最初lastSeq = 0.当Poller得到结果列表时,它用max SEQ值替换lastSeq。 fullPoll仅检索带有SEQ&gt;的记录。 lastSeq。

void run() throws Exception {
    int seqId = 0;
    while(true) {
          List<KpiMessage> list = fullPoll(seqId);
          if (!list.isEmpty()) {
            seqId = list.get(0).getSequene();
          }
          Thread.sleep(6000); 
    }
}

public List<KAMessage> fullPoll(int lastSeq) throws Exception {
       ...
       ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION =  804 and SEQ > " + lastSeq + " order by SEQ 
      DESC");     
      .. 
}

答案 1 :(得分:1)

以下是您可能用于处理的一些代码。我尝试使用Observer模式使其非常灵活;这样,您可以将多个“消息处理器”连接到同一个轮询器:

public class MessageRetriever implements Runnable {
    private int lastID;
    private List<MessageListener> listeners;

   ...

    public void addMessageListener(MessageListener listener) {
        this.listeners.add(listener)
    }

    public void removeMessageListener(MessageListener listener) {
        this.listeners.remove(listener)
    }

    public void run() {
        //code to repeat the polling process given some time interval    
    }  

    private void pollMessages() {
        if (this.lastID == 0)
            this.fullPoll()
        else
            this.partialPoll()           
    }

    private void fullPoll() {
        //your full poll code

        //assuming they are ordered by ID and it haves the ID field - you should
        //replace this code according to your structure
        this.lastID = pojoCol.get(pojoCol.length() - 1).getID() 

        this.fireInitialMessagesSignal(pojoCol)
    }

    private void fireInitialMessagesSignal(List<KAMessage> messages) {
        for (MessageListener listener : this.listeners)
            listener.initialMessages(messages)
    }

    private void partialPoll() {
        //code to retrieve messages *past* the lastID. You could do this by 
        //adding an extra condition on your where sentence e.g 
        //select * from msg_new_to_bde where ACTION = 804 AND SEQ > lastID order by SEQ DESC
        //the same as before
        this.lastID = pojoCol.get(pojoCol.length() - 1).getID() 

        this.fireNewMessagesListener(pojoCol)
    }

    private void fireNewMessagesListener(List<KAMessage> messages) {
        for (MessageListener listener : this.listeners)
            listener.newMessages(messages)
    }

}

界面

public interface MessageListener {
    public void initialMessages(List<KAMessage> messages);
    public void newMessages(List<KAMessage> messages)
}

基本上,使用这种方法,检索器是一个可运行的(可以在它自己的线程上执行)并负责整个过程:进行初始轮询并继续在给定的时间间隔内进行“部分”轮询。

不同的事件触发不同的信号,将受影响的消息发送给已注册的侦听器,然后根据需要处理消息。