Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: How not to send message?

  1. #1
    Join Date
    Jun 2011
    Posts
    7

    Default How not to send message?

    Hello all =)

    I use Tcp from receiving massages from device. Sometimes device open Tcp connect and close without any payload.

    I use deserializer in tcp-connection-factory.
    deserializer tryes to read anything from Stream, if there is something - it return founded thing...
    But when nothing are come - i return null, and Spring Integrations throws exception "can not send message: null".

    How can i correctly say to Spring that NO MESSAGE EXIST, so no processing shold be done.

  2. #2
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    Could you post your configuration?
    The message is correct, we don't allow messages with the 'null' payload, however, i am curious to see why it even attempts to create a Message with 'null' payload. We may need to improve there.

  3. #3
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,145

    Default

    Which deserializer are you using?

    If it's a custom one, you need to throw a SoftEndOfStreamException to signal a 'clean' close.

    For example, in the ByteArrayCrLfSerializer...

    Code:
    if (bite < 0 && n == 0) {
    	throw new SoftEndOfStreamException("Stream closed between payloads");
    }
    If you are using one of our deserializers, please attach a debug log showing the error.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  4. #4
    Join Date
    Jun 2011
    Posts
    7

    Default

    2 Oleg:

    <int-ip:tcp-connection-factory
    id="tcpInFactory-Device"
    type="server"
    port="***"
    using-nio="false"
    serializer="byteArrayLfConverter"
    deserializer="byteArrayLfConverter"

    pool-size="200"
    so-keep-alive="false"
    so-timeout="10000"
    />

    <int-ip:tcp-inbound-channel-adapter
    id="tcpInAdapter-Device"
    channel="inChannel-Device"
    connection-factory="tcpInFactory-Device"
    />

    <int:channel id="inChannel-Device" />
    byteArrayLfConverter is similar to ByteArrayCrLfSerializer written by Spring.

  5. #5
    Join Date
    Jun 2011
    Posts
    7

    Default

    "The message is correct, we don't allow messages with the 'null' payload, however, i am curious to see why it even attempts to create a Message with 'null' payload. We may need to improve there"

    TCP channel is opened, but NO payload are come. And channel are closed. Whay should i do in deserializer?

    SoftEndOfStreamException -is not correct solution. It's an exception and it will be written to logs and admins will receive email that "SOMETHING BAD APPEARED - WE GOT EXCEPTION".

  6. #6
    Join Date
    Jun 2011
    Posts
    7

    Default

    2 Gary:

    Hi, how are you? I use your code with modifications:

    Code:
    public byte[] deserialize(InputStream inputStream) throws IOException {
            try {
                byte[] buffer = new byte[this.maxMessageSize];
                int n = 0;
                int bite;
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Some data arrived");
                }
                while (true) {
                    try {
                        bite = inputStream.read();
                        if (bite < 0 && n == 0) {
                            throw new SoftEndOfStreamException("Stream closed between payloads");
                        }
                        checkClosure(bite);
                        //if message has non zero elements - end of message
                        if (n > 0 && bite == '\n') {
                            break;
                        }
                        //skipping \n data, because some devices send \n as TCP connection "heat beats"
                        if (bite != '\n') {
                            buffer[n++] = (byte) bite;
                            if (n >= this.maxMessageSize) {
                                throw new IOException("CRLF not found before max message length: "
                                        + this.maxMessageSize);
                            }
                        }
                    } catch (SocketTimeoutException timeoutException) {
                        break;      //on timeout we trying to continue with all already read data
                    }
                }
                //if n is ZERO - mean socket closed without any payload
                if (n == 0) {
                    // HERE IS PROBLEM!!! What should i do to correctly say to Spring - no message exist, continue work without Exceptions
                    throw new SoftEndOfStreamException("No data are readed from channel");
                }
                byte[] assembledData = new byte[n];
                System.arraycopy(buffer, 0, assembledData, 0, n);
                LOG.debug("some data readed, size {}", n);
                return assembledData;
            } catch (RuntimeException re) {
                LOG.error("error during data reading", re);
                throw re;
            } catch (IOException e) {
                LOG.error("IOException during data reading", e);
                throw e;
            }
        }

  7. #7
    Join Date
    Jan 2009
    Location
    Ukraine, Kharkov
    Posts
    736

    Default

    Hello,
    I think, SoftEndOfStreamException - is the best solution.
    Your can define on your tcp-adapter an error-channel. And in the end you must write simple ErrorUnwrapper. That one checks Exception from message via instanceof SoftEndOfStreamException and doesn't send outbound message to reply-channel.

    Is it suitable?

    Artem

  8. #8
    Join Date
    Jun 2011
    Posts
    7

    Default

    2 Cleric:

    AFAIK Exception is UBNORMAL situation. And no data in socket is normal for my application.
    Also AFAIK Exception handling is much more consuming than work without Exception

    for example
    Code:
            if(obj == null) {
                doSomeStuff();
            }
    will be much faster than
    Code:
            try {
                obj.getSomething()
            } catch (NullPointerException ex) {
                doSomeStuff();
            }
    is not it?

    And in my case possible that for one piece of cake i will receive ten empty connections.

  9. #9
    Join Date
    Jan 2009
    Location
    Ukraine, Kharkov
    Posts
    736

    Default

    if(obj == null) {
    doSomeStuff();
    }
    But it's not logic of deserializer...

  10. #10
    Join Date
    Jun 2011
    Posts
    7

    Default

    I mean that no sense to use Exception in logically normal situation.


    Code:
    readData() {
    ...
                //if n is ZERO - mean socket closed without any payload
                if (n == 0) {
                    // HERE IS PROBLEM!!! What should i do to correctly say to Spring - no message exist, continue work without Exceptions
                    throw new SoftEndOfStreamException("No data are readed from channel");
                }
    ...
    }
    
    try { 
        readData();
    } catch (SoftEndOfStreamException ex) { 
        //just skip message
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •