Tigase 플러그인 – 플러그인 작성

7766 단어
이전 글은 XMPP stanza가 세션 관리자에서 어떻게 처리되는지 설명합니다.처리는 네 단계로 나뉘는데 각 단계마다 상응하는 유형의 플러그인이 처리를 책임진다.
  • 첫 번째 단계 - 사전 처리 – XMPPPreprocessorIfc: 사전 프로세서 플러그인에 필요한 인터페이스
  • 2단계 – 처리 – XMPPProcessorIfc: 프로세서 플러그인에 필요한 인터페이스
  • 3단계 - 배달 - XMPPpostProcessorIfc: 배달 프로세서 플러그인에 필요한 인터페이스
  • 4단계 - 필터 – XMPPpacketFilterIfc: 결과 필터 플러그인에 필요한 인터페이스
  • 만약 네가 이미 이 네 인터페이스의 코드를 보았다면, 모든 인터페이스는 오직 하나의 방법만이 실현되어야 한다는 것을 발견할 수 있을 것이다.그렇습니다. 이 방법은 Packet을 처리하는 데 매우 비슷한 입구 파라미터를 가지고 있습니다. 다음에 이 파라미터에 대해 소개합니다.
  • Packet packet - 처리해야 하는 packet - 이 매개 변수는null일 수 없습니다.설령 이 대상이immutable이 아니더라도 방법에서는 그것을 수정할 수 없다.그것의 어떤 것도 밝아지면 변할 수 없다.
  • XMPPResourceConnection session – session에는 모든 사용자 세션 데이터와 사용자 데이터베이스에 접근하는 방법이 포함되어 있습니다.그것은 영구화 데이터베이스에 정보를 저장할 수 있지만, 사용자가 온라인에서 메모리에만 데이터를 저장할 수 있다면.방법이 호출될 때, 온라인 사용자 세션이 없으면, 이 인자는null일 수 있습니다.
  • NonAuthUserRespository repo - 위의 매개 변수 - 즉 사용자 세션이 비어 있을 때 이 매개 변수는 보통 사용자 데이터를 저장하는 데 사용된다.그것은 매우 제한된 데이터 접근만 허용한다.예를 들어 사용자가 오프라인 상태일 때 사용자의 오프라인 메시지를 저장한다. (이미 존재하는 데이터에 대해서는 덮어쓰기를 허용하지 않는다.) 예를 들어 사용자의 공공 V카드 정보를 읽는다.
  • Queueresults - 처리된 결과 패키지 대기열입니다.어쨌든 입력한 패키지를 백업하고 결과 그룹에 저장해야 합니다.
  • Map setting – 맵에tigase 서버가 플러그인을 위한 설정 정보를 저장합니다.대부분의 경우 플러그인은 이러한 설정 정보를 필요로 하지 않지만, 어떤 플러그인이 외부 데이터베이스에 접근해야 한다면,tigase 서버는 이 파라미터를 통해 데이터베이스 연결 문자열을 전달할 수 있다.

  • 위의 인터페이스를 자세히 보면 extend XMPPimplIfc 인터페이스가 있습니다.XMPPImplIfc는 플러그인의 기본 meta 정보를 얻을 수 있는 인터페이스를 정의합니다.다음 소스 참조:
    /**
     *     XMPPImplIfc     
     */
    public interface XMPPImplIfc {
        int concurrentQueuesNo();
     
        @Deprecated
        int concurrentThreadsPerQueue();
     
        /**
         * id()       ID。          ID:                   ,     。
         *       ,ID         packet XMLNS。
         *
         * @return id,     
         */
        String id();
     
        /**
         * init()                  ,                            。
         *                           scheme             。
         *
         * @param settings        
         * @throws TigaseDBException
         */
        void init(Map settings) throws TigaseDBException;
     
        //~--- get methods ----------------------------------------------------------
     
        /**
         * isSupporting              ,            “   ”
         *
         * @param elem     ,     
         * @param ns       ,     
         * @return       ,true:   ;false:    
         */
        boolean isSupporting(String elem, String ns);
     
        //~--- methods --------------------------------------------------------------
     
        /**
         * supDiscoFeatures()             XML           (service discovery)    。
         *                      。
         *
         * @param session   XMPPResourceConnection  
         * @return   XML    
         */
        Element[] supDiscoFeatures(XMPPResourceConnection session);
     
        /**
         * supElements()       “   ” XML     ,                 supNamespaces()       
         *
         * @return      
         */
        String[] supElements();
     
        /**
         * supNamespaces()       “   ” stanza    ,                  supElements()     XML   
         *
         * @return      
         */
        String[] supNamespaces();
     
        /**
         * supStreamFeatures()             XML            。
         *                   。
         *
         * @param session   XMPPResourceConnection  
         * @return XML    
         */
        Element[] supStreamFeatures(XMPPResourceConnection session);
    }

    다음에, 우리는 <메시지/> 패키지를 전문적으로 처리하는 간단한 플러그인을 실현합니다. 플러그인의 작업은 패키지를 목적지 주소로 배달하는 것입니다.전송된 패키지는 사용자에게 전송되고 전송된 패키지는 외부 목적지 주소로 전송됩니다.이 플러그인은 SVN 서버에 저장되어 있습니다 (https://svn.tigase.org/reps/tigase-server/trunk/src/main/java/tigase/xmpp/impl/Message.java).코드에는 약간의 비고가 있지만, 이 문서는 실현 세부 사항을 더욱 깊이 있게 소개할 것이다.
    시작하기 전에 플러그인 형식을 선택해야 합니다.프로세서 플러그인을 개발하려면 XMPPprocessorIfc 인터페이스를 실현해야 한다.예처리 플러그인이라면 XMPPPreprocessorIfc 인터페이스를 실현해야 한다.물론 너도 여러 인터페이스를 실현할 수 있다. 이것은 너의 요구와 상황에 달려 있다. 너도 helper 추상 클래스를 기본 클래스로 모든 플러그인을 실현할 수 있다.플러그인 클래스의 설명은 다음과 같아야 합니다. (만약 프로세서 플러그인을 실현하려면)
    public class Message extends XMPPProcessor
        implements XMPPProcessorIfc

    가장 먼저 해야 할 일은 플러그인 ID를 확인하는 것입니다.이것은 유일하게 설정 파일에 넣어서 서버가 시작할 때 해당하는 플러그인을 불러오고 사용하도록 알려야 한다.만약 이 플러그인이 특정 이름 공간에서 특정 이름의 요소만 '관심' 있다면, 대부분의 경우, 직접 이름 공간으로 ID를 만들 수 있다. 물론, 이 이름의 요소가 다른 패키지에 나타나지 않을 것이라고 누구도 보장할 수 없다.모든 프로세서 플러그인을 처리할 수 있는 플러그인을 개발하고 싶지만, 이 플러그인에 멋진 ID를 만드는 방법을 하루 종일 생각하고 싶지 않기 때문에 차라리 '메시지' 라고 부르자.
    플러그 인의 ID는 다음 코드로 설명합니다.
    private static final String ID = "message";
    public String id() { return ID; }

    앞에서 설명한 바와 같이 플러그인은 '관심 있는' 패키지만 수신하고 처리합니다.우리의 플러그인은 'jabber:client' 명칭 공간의 요소에만 관심이 있습니다.플러그 인이 관심 있는 항목을 설명하려면 다음 두 가지 방법을 추가해야 합니다.
    public String[] supElements() {
      return new String[] {"message"};
    }
     
    public String[] supNamespaces() {
      return new String[] {"jabber:client"};
    }

    현재 우리는 플러그인을tigase 서버에 불러올 준비가 되어 있습니다.다음 단계는 패키지 처리를 실현하는 쪽입니다. 원본 코드 (tigase.xmpp.impl.Message.java) 를 참고하십시오.나는 곤혹스러워하기 쉬운 코드에 주석을 달고 한두 줄의 코드를 추가해서 네가 이해할 수 있도록 도와줄 뿐이다.
    public void process(final Packet packet,
        final XMPPResourceConnection session,
        final NonAuthUserRepository repo,
        final Queue<Packet> results,
        final Map<String, Object> settings)
        throws XMPPException {
     
      //        ,                  
      if (log.isLoggable(Level.FINEST)) {
        log.finest("Processing packet: " + packet.toString());
      }
     
      //        ,             
      if (session == null) {
        return;
      } // end of if (session == null)
     
      //                      ,                 
      if (session.getSessionData(ID) == null) {
        session.putSessionData(ID, ID);
        //             
        .....
        //           ,    return    
        return;
      }
     
      //            ,       session.getUserId()        
      try {
     
        //    JID         resource  
        // JID   :jid = [ node "@" ] domain [ "/" resource ]
        //   :[email protected]/home
        String id = JIDUtils.getNodeID(packet.getElemTo());
        //       packet           
        if (session.getUserId().equals(id)) {
          //    ,                   
          Element elem = packet.getElement().clone();
          Packet result = new Packet(elem);
          //                              
          //       ,                 c2s Bosh  
          result.setTo(session.getConnectionId(packet.getElemTo()));
          //       ,       ,   packet            ,               
          result.setFrom(packet.getTo());
          //          packet         ,       
          results.offer(result);
        } // end of else
     
        //    JID         resource  
        id = JIDUtils.getNodeID(packet.getElemFrom());
        //       packet           
        if (session.getUserId().equals(id)) {
          //            packet,         packet   packet      :
          //     XML      ,  ……
          Element result = packet.getElement().clone();
          //       packet       
          results.offer(new Packet(result));
          return;
        }
     
        //            ?
        //   ,  packet   from   to  。                         IQ  。  packet      ,              
        //               seesion        session
        id = packet.getFrom();
        //         getElementFrom   
        if (session.getConnectionId().equals(id)) {
          //       IQ packet       ,          message,             
          Element result = packet.getElement().clone();
          //            packet from      ,   from      
          result.setAttribute("from", session.getJID());
          //      packet         ok 
          results.offer(new Packet(result));
        }
     
      } catch (NotAuthorizedException e) {
        log.warning("NotAuthorizedException for packet: "   +
          packet.getStringData());
        results.offer(Authorization.NOT_AUTHORIZED.getResponseMessage(packet,
          "You must authorize session first.", true));
      } // end of try-catch
     
    }

    좋은 웹페이지 즐겨찾기