Search code examples
jmsprotocolsmessage

Which protocol to use for sending JMS messages?


I need some advise to implement the best protocol (not http, tcp, ...) te send messages.

  • Should I send Serialized Objects? (POJO's)
  • Should I send technology independent XML messages?
  • What would be recommended? Both will work, but what is best practice. Sharing a library is not what I prefer, but is it easy to work with XML? Are there better alternatives? Thanks in advance!

I have one server, with a 1000 clients connected. The server delivers task to the clients. The clients send information back after executing different tasks.

How should I send a task to a JMS client with some parameters?

A task is nothing more than an action and some parameters.

  • Example: "action=measure; parameters: duration=100sec; samples=100" --> collect 100 samples during 100 seconds.
  • Example: "action=config; parameters: set of configuration parameters" --> to change the client configuration
  • Example: "action=stop" --> Stop the client (the system wil restart after a daily reboot)

A report is nothing more than data.

  • Example: "list of 100 values from measurement"
  • Example: "the content of a log-file"

I have read many articles, but couldn't find an answer for this question. Thanks in advance.


Solution

  • This is our current implementation.

    We define a protocol with an XSD and let this generate classes (POJO's). This allows us to marshal/unmarshal the objects and send them as XML objects.

    Our XSD:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               jaxb:version="2.0">
    
        <!-- Ping
            The server will send a ping to a client and waits for a pong.
        ****************************************************************** -->
        <xs:element name="Ping">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="client" type="xs:string"/>
                    <xs:element name="message" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    
        <!-- Pong
            The client will send a pong back to the server.
        ****************************************************************** -->
        <xs:element name="Pong">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="client" type="xs:string"/>
                    <xs:element name="message" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    
        <!-- Alive
            The client will send an alive message when it starts up.
            The time is local client time.
        ****************************************************************** -->
        <xs:element name="Alive">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="client" type="xs:string"/>
                    <xs:element name="time" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    
        <!-- ... Many more message definitions ...
        ****************************************************************** -->
    
    </xs:schema>
    

    Our test class:

    public class JaxbFacadeTest {
    
        @Test
        public void testPing() throws JAXBException, SAXException, UnsupportedEncodingException {
            System.out.println("testPing");
            Ping ping = new Ping();
            ping.setClient("guid-client");
            ping.setMessage("Ping Message");
            String marshalToString = JaxbFacade.getInstance().marshalToString(ping);
            System.out.println(marshalToString);
        }
    
        @Test
        public void testPong() throws JAXBException, SAXException, UnsupportedEncodingException {
            System.out.println("testPong");
            Pong pong = new Pong();
            pong.setClient("guid-client");
            pong.setMessage("Ping Message");
            String marshalToString = JaxbFacade.getInstance().marshalToString(pong);
            System.out.println(marshalToString);
        }
    
        @Test
        public void testAlive() throws JAXBException, SAXException, UnsupportedEncodingException {
            System.out.println("testAlive");
            Date now = new Date();
            Alive alive = new Alive();
            alive.setClient("guid-client");
            alive.setTime(now.toString());
            String marshalToString = JaxbFacade.getInstance().marshalToString(alive);
            System.out.println(marshalToString);
        }
    
        //Many more
    }
    

    The classes are generated with maven:

    <build>
        <resources>
            <resource>
                <directory>${project.basedir}/src/main/xsd</directory>
                <targetPath>com/test/package/client/jaxb</targetPath>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.jvnet.jaxb2.maven2</groupId>
                <artifactId>maven-jaxb2-plugin</artifactId>
                <executions>
                    <execution>
                        <id>jaxb</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <generatePackage>com.test.package.client.jaxb</generatePackage>
                    <schemaDirectory>${project.basedir}/src/main/xsd</schemaDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>