AbstractXmppConnection的静态实例:向ejabberd缓慢传递消息

时间:2016-06-30 08:26:50

标签: ejabberd smack

我正在从smack库(Java)向Ejabberd发送消息(自动化)。如何完成: -

AbstractXmppConnection的静态对象是为一个用户创建的 - 每次api命中,发布连接后,都会通过连接向Ejabberd发送消息

问题:Java Play Framework上有大约400次连续点击来自python脚本。脚本和api运行正常,通过日志检查。问题是消息延迟到达用户。在2个消息拍摄之间,有大约一分钟的延迟。如果我检查mysql数据库,归档表,第一次命中只有一个条目,连续条目变得非常慢。

但是,如果我将AbstractXmppConnection作为类的实例并按照连接,shootMessage和每次命中的断开流程,则会立即发送消息。但是连接和断开同一帐户如此之快会增加Ejabberd的负载。

问题:为什么重复使用AbstractXmppConnection的同一个(静态)对象在发送消息时发送多个消息非常慢?当我必须为每个api命中创建新实例时,它的快速

代码(多个实例:工作速度快但由于连接/断开频率而增加负载):

public synchronized void sendMessage(String senderId,String receiverId, String SERVER, Message message) throws IOException, XMPPException, SmackException {
+        Logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@SENDING MESSAGE TO "+receiverId + " from "+senderId+ " Message "+message.toXML().toString());
+
+        AbstractXMPPConnection abstractXMPPConnection;
+
+        //Making connection
+        EjabberdConnectionQuote ejabberdConnection = new EjabberdConnectionQuote();
+        abstractXMPPConnection = ejabberdConnection.getConnection();
+        abstractXMPPConnection.login(senderId,"secret");
+
+        //Create chat
+        Chat chat = null;
+        ChatManager chatManager = null;
+        chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); //$$$$$NEW INSTANCE$$$$
+        chat = chatManager.createChat(receiverId + SERVER);
+        chat.sendMessage(message);
+
+        abstractXMPPConnection.disconnect();
+
+        if (abstractXMPPConnection.isConnected() ){
+            Logger.info("Still Connected");
+        }else{
+            Logger.info("<---------Disconnected------->");
+        }
+ }

代码(静态连接对象重用于所有api命中,模仿一个用户并向Roster中的许多用户开枪):

 AbstractXMPPConnection abstractXMPPConnection;
+        SingletonConnection obConn = SingletonConnection.getInstance();
+        if ( obConn.connectionMap.containsKey(senderId) ) {
+            Logger.info("Already Connected");
+            //Remove and update timer
+            obConn.updateTimer(senderId);
+            abstractXMPPConnection = obConn.connectionMap.get(senderId).abstractXMPPConnection;

+        }else{
+            Logger.info("Creating new connection");
+            //Create new connection and put it in map
+            EjabberdConnectionQuote ejabberdConnection = new EjabberdConnectionQuote();
+            abstractXMPPConnection = ejabberdConnection.getConnection();
+            abstractXMPPConnection.login(senderId,"secret");
+            RemoveConnectionTimer removeConnectionTimer = new RemoveConnectionTimer(senderId);
+            StoreData storeData = new StoreData(senderId,abstractXMPPConnection,removeConnectionTimer);
+            obConn.connectionMap.put(senderId,storeData);
+
+        }



 Message message = createMessage(quote, returnDateInIst(), senderId, receiverId);
         String key = receiverId + "$$$" + senderId;

-        SingletonConnection.getInstance().sendMessage(senderId,receiverId,SERVER,message);
+        Chat chat = null;
+        ChatManager chatManager = null;
+        chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); //$$$$$REUSE EXISTING connection$$$$
+        chat = chatManager.createChat(receiverId + SERVER);
+        chat.sendMessage(message);
+
+        //abstractXMPPConnection.disconnect();
+
+        if (abstractXMPPConnection.isConnected() ){
+            Logger.info("Still Connected");
+        }else{
+            Logger.info("<---------Disconnected------->");
+ }

1 个答案:

答案 0 :(得分:0)

经过多次记录和检查smack源代码后,我找到了原因。

    chatManager = ChatManager.getInstanceFor(abstractXMPPConnection); 
    chat = chatManager.createChat(receiverId + SERVER);
    chat.sendMessage(message);

上面的代码片段返回一个聊天对象,只能由实例化的abstractXMPPConnection对象的线程访问。如果从其他线程访问对象,则它为null。