Turn: http://phoenixtoday.blogbus.com/logs/17878527.html
I will continue to introduce the blog developed based on XMPP Im in March 18. Today I will mainly summarize how to add client functions based on the spark plug-in architecture, the following is an example of how to obtain group information on the server:
Spark is an IM Client implemented in Java based on the XMPP protocol. It provides some APIs that can be extended using the plug-in mechanism. In the middle, the "department" section is a new function extended using the plug-in mechanism. To implement your expansion, you must first understand the spark API architecture. The most important thing is to understand its factory class, these factory classes can obtain instances such as xmppconnection and chatcontainer provided by Spark, so that you can obtain server information and communicate with other clients. The core class is sparkmanager, which is a series of factory classes ). Its getchatmanager (), getsessionmanager (), getmainwindow (), and getconnection () methods can obtain useful instances such as the chat manager, Session Manager, main window, and connection to the server. Basically speaking, sparkmanager is the interface between you and spark. In fact, every manager uses the singleton mode. You can also retrieve them without using sparkmanager. However, I suggest you start with a single entry, which is conducive to code development and maintenance.
Next, describe the development process of the plug-in:
1. Create the plug-in configuration file plugin. xml
2. Implement your own plugin class (if you need to implement XML sending, receiving, and processing in the prescribed format, you need to register your iqprovider here, you can query the smack API about iqprovider. In simple terms, it is used to process your custom IQ processor .)
3. Package Your plug-in (spark has its own packaging mechanism. I studied it for half a day and found the xuanjicang. I will introduce it later)
4. Deploy your plug-in (in fact, Steps 3 and 4 can be combined, and ant must be used)
The following describes the above four steps based on an actual example.
1. plugin. xml
<Plugin>
<Name> enterprise IM client </Name>
<Version> 1.0 </version>
<Author> Phoenix </author>
<Homepage> http://phoenixtoday.blogbus.com <Email> phoenixtoday@gmail.com </Email>
<Description> enterprise client plug-in </description>
<! -- The key is here. Here we need to define your plugin class -->
<Class> com. Im. plugin. implugin </class>
<! -- The minimum spark version you are using is defined here -->
<Minsparkversion> 2.5.0 </minsparkversion>
<OS> Windows </OS>
</Plugin>
This is the content of a plugin. xml file. The plug-in system will automatically call the plugin class you defined in this file to complete your own extended functions. The most important part is marked in red. to declare your plug-in extension class, use the complete namespace method (including the package name). The rest is combined with my comments, we should be able to understand it, so we will not describe it in detail. Note that the plugin. xml file should be placed under the root directory of the project, which is strictly required.
2. Implementation of the plugin class
Your class must first implement the plug-in interface provided by spark, and then implement some of its methods. Among them, the most important thing is to implement initialize () issuance. register your iqprovider here
Providermanager = providermanager. getinstance ();
Providermanager. addiqprovider ("groups", "com: Im: Group", // 1
New grouptreeiqprovider ());
System. Out. println ("register grouptree IQ provider ");
Requestgrouptree ();
The above code is the implugin I implemented in this class. a short section in the initialize () method, which roughly means obtaining providermanager first (this does not seem to be available directly from sparkmanager), and then registering a grouptreeiqprovider (created by yourself) this is an iqprovider implementation. It is used to parse an XML file like the following:
<? XML version = "1.0" encoding = "UTF-8"?>
<IQ type = 'result' to = 'domain @ server.com 'from = 'phoenixtoday @ gmail.com' Id = 'request _ 1'>
<Groups xmlns = 'com: Im: group'>
<Group>
<Groupid> 1 </groupid>
<Name> Xi'an Jiaotong University </Name>
<Upgroup> root </upgroup>
<Isleaf> 0 </isleaf>
<Description> xjtu </description>
<User>
<Usergroupid> 1 </usergroupid>
<Username> phoenix_test </username>
<Role> normal </role>
</User>
</Group>
<Group>
<Groupid> 2 </groupid>
<Name> Institute of Telecommunications </Name>
<Upgroup> 1 </upgroup>
<Isleaf> 1 </isleaf>
<Description> xjtu info </description>
</Group>
</Groups>
</IQ>
You can see that when registering iqprovider (part 1 marked in the Code), you need to provide the name and namespace, the first child node in IQ in my XML file is <Groups>, so my name is "groups". The namespace corresponds to the xmlns (XML Name Space) of the groups node) therefore, it is "com: Im: Group". In fact, the most critical method of iqprovider is parseiq (xmlpullparser parser). This method is to parse XML and complete your functions, and return a corresponding IQ instance (here we can regard IQ as a feedback model class ). In the end, the implementation of the XMPP protocol based IM is to parse the XML file, which is exactly what the client iqprovider and the server iqhandler (which will be involved in the next article) Do.
3. Package Your plug-in
Now all the functions are implemented, so it is packaged. It is best to use ant to complete this, because every time you package, you need to deploy it. If it is manual, it is too agile, which greatly affects the development efficiency.
<? XML version = "1.0" encoding = "UTF-8"?>
<Project name = "im" default = "release" basedir = ".">
<Property name = "src. dir" value = "src"/>
<Property name = "DeST. dir" value = "bin"/>
<Property name = "Lib. dir" value = "lib"/>
<Property name = "im. path"
Value = "E:/workspace/Europa/spark_new/doc/spark/target/build"/>
<Target name = "clean">
<! --
<Delete dir = "$ {DeST. dir}"/>
<Delete dir = "$ {Lib. dir}"/>
-->
</Target>
<Target name = "init" depends = "clean">
<! --
<Mkdir dir = "$ {DeST. dir}"/>
<Mkdir dir = "$ {Lib. dir}"/>
-->
</Target>
<Target name = "build" depends = "init">
<! --
<Javac srcdir = "$ {SRC. dir}" destdir = "$ {DeST. dir}"/>
-->
</Target>
<! -- The most important thing is to pack the package twice -->
<Target name = "jar" depends = "build">
<Jar jarfile = "$ {Lib. dir}/EIM. Jar" basedir = "$ {DeST. dir}"/>
<Jar jarfile = "$ {im. Path}/plugins/EIM. Jar">
<Fileset dir = ".">
<Include name = "lib/*. Jar"/>
</Fileset>
<Fileset dir = ".">
<Include name = "plugin. xml"/>
</Fileset>
</Jar>
</Target>
<Target name = "release" depends = "jar">
<! --
<Exec executable = "cmd.exe"
Failonerror = "true">
<Arg line = "/c e:"/>
<Arg line = "/c Cd workspace/Europa/spark_new/doc/spark/target/build/bin"/>
<Arg line = "/C startup. Bat"/>
</Exec>
-->
</Target>
</Project>
This is the content in the build. xml file of my project. Because eclipse actually helped me to automatically complete the compilation task, so I also saved this compilation step. The most important thing is that you should see the "jar" section, this is the secret of spark packaging. Pack your project to the Lib folder of the project after two packages. For example, if your project directory is myplugin, you can package your class to the myplugin/lib directory, and then package it again to package all the content in the Lib folder. Remember to include plugin this time. XML. In other words, the spark plug-in system will read the content in the Lib folder of your project. Here I also have a question: I originally wanted to automatically execute the BAT file after each package, start the plug-in, and check the effect. Why can't I call it? The code is at the end, commented out. Who can help me solve the problem? I invite him to dinner!
4. Finally, it is released.
In fact, my release is very simple. It is to copy the packaged JAR file to the Plugins directory of spark itself. Every time spark is started, it will automatically call the custom plug-in. When I used the ant jar for the second time, I automatically copied it. Here we use absolute paths, so you can't copy it directly. (isn't it ugly, this ant code ).
Basically, the implementation principle of the client is like this, but in some cases, special attention should be paid, and tools like ant should be used to greatly simplify the development steps and speed up the development efficiency. I also recommend that you use the MVC mode when developing your own plug-ins, especially after iqprovider resolution, the generated part can be instantiated with the model, then you can write your own manager to process these models. Write more logs. Of course, log4j does not seem to work very well. Let's talk about system. Out. println (). Haha! I wrote it here today, but I'm tired of it.