Announcement Announcement Module
Collapse
No announcement yet.
how to connect webservice to tcp system? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • how to connect webservice to tcp system?

    I'm trying to connect a web service ( SOAP, write with Spring WS ) to a linux service ( it was write in C and send data to xxxx port ). I need to send string data to this system and receive a response and then web service send data by SOAP to the customers. I'm using Spring Integration to connect through TCP ( sockets ), but I maybe dont understand the framework architecture. I suppose my web service is the client and the linux system is the server, so I configure a tcp-inbound-gateway ( because I need the response and to control a timeout ) but in testing send data and then connection close inmediately, I need to know how to wait and to capture the response to be able send by method's web service ( EndPoint )

    Code:
    <int-ip:tcp-connection-factory id="client"
        type="client"
        host="localhost"
        port="8001"
        single-use="true"
        so-timeout="10000"
      />
      <int-ip:tcp-outbound-gateway id="outGateway"
        request-channel="requestChannel"
        reply-channel="replyChannel"
        connection-factory="client"
        request-timeout="100000"
        reply-timeout="100000"  
        />
    
    	<int:channel id="replyChannel"/>
    	<int:channel id="requestChannel" />
    method web service :

    Code:
            @PayloadRoot(namespace = NAMESPACE_URI, localPart = REQUEST_LOCAL_NAME)
    	@ResponsePayload
    	 public WSResponse processRequest(@RequestPayload WSRequest wsRequest)   {            
    	
    	 Message<String> message = MessageBuilder.withPayload("DATA").build();
    	 MessageChannel channel = channelResolver.resolveChannelName("requestChannel");
    	 boolean x = channel.send(message,10000); // so, this code doesnt wait for response.
             ....
    
    }

  • #2
    The easiest way is to use a messaging gateway.

    http://static.springsource.org/sprin...r.html#gateway

    Then, your WS doesn't even know it's using SI to talk to the TCP server.

    You simply call a method on the interface that sends and receives the data.

    Comment


    • #3
      code return same message

      Thks, but I still donīt understand good. I write the next code but its return the same message I send from client:

      Code:
       <int-ip:tcp-connection-factory id="client"
          type="client"
          host="192.168.1.2"
          port="8001"
          single-use="false"
          so-timeout="3000"
          using-nio="false"	
          serializer="serializer" deserializer="serializer"
        />
       <int:gateway id="gw"
              service-interface="com.ServiceTesting"
              default-request-channel="input"
              error-channel="exceptionTransformationChannel"  />
       
      
      <bean id="errorTransformer"
      		  class="com.ErrorTransformer" />
       
       <int:transformer input-channel="exceptionTransformationChannel"
              ref="errorTransformer" method="show" />
              
         <int:channel id="reply"  datatype="java.lang.String" />
        
         <int:channel id="exceptionTransformationChannel" />
         
         <int-ip:tcp-outbound-channel-adapter id="outAdapter.client"
          channel="input"
          connection-factory="client"/>
        
         <int:publish-subscribe-channel id="input" datatype="java.lang.String"/>
          
          <int:bridge input-channel="input" output-channel="toAggregator.client"
      			order="1"/>
      
      	<!-- Asynch receive reply -->
      	<int-ip:tcp-inbound-channel-adapter id="inAdapter.client"
      		channel="toAggregator.client"
      		connection-factory="client" /> <!-- Collaborator -->
      
      	<!-- dataType attribute invokes the conversion service, if necessary -->
      	<int:channel id="toAggregator.client" datatype="java.lang.String" />
      
      	<int:aggregator input-channel="toAggregator.client"
      		output-channel="toTransformer.client"
      		correlation-strategy-expression="payload.substring(0,3)"
      		release-strategy-expression="true" />
      
      	<int:transformer input-channel="toTransformer.client"
      		expression="payload.get(0)"/>

      Comment


      • #4
        After the aggregation, the payload is a list, with the first entry being the original message and the second is the reply.

        You need to change get(0) to get(1) in the transformer (as is done in the sample, from which it appears you got this code).

        Comment


        • #5
          Thks Gary, but when I write get(1) shows:


          Caused by: org.springframework.integration.MessageHandlingExc eption: Expression evaluation failed: payload.get(1)
          at org.springframework.integration.util.AbstractExpre ssionEvaluator.evaluateExpression(AbstractExpressi onEvaluator.java:100)
          at org.springframework.integration.handler.Expression EvaluatingMessageProcessor.processMessage(Expressi onEvaluatingMessageProcessor.java:67)
          at org.springframework.integration.transformer.Abstra ctMessageProcessingTransformer.transform(AbstractM essageProcessingTransformer.java:56)
          at org.springframework.integration.transformer.Messag eTransformingHandler.handleRequestMessage(MessageT ransformingHandler.java:67)
          ... 84 more
          Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1


          I don't understand the reason because I when write code in traditional way with socket, it's return correct result, but I need to control each response belong a request, and timeout ( for than reason I choose SI ). I suppose I wrong in some point. I appreciate you great help.

          The code (this run very good ) without spring integration is:


          Code:
                           Clientsocket = new Socket("192.168.1.2", 8001);
          		       OutSocket = new DataOutputStream(Clientsocket.getOutputStream());
          		       InpSocket = new BufferedReader(new InputStreamReader(Clientsocket.getInputStream()));
          				 
          			   OutSocket.flush();
          			   OutSocket.writeBytes("testing message \n");
          			   OutSocket.flush();
          			   result = InpSocket.readLine(); // show correct result
          			   Clientsocket.close();
          	           InpSocket.close();
          	           OutSocket.close();

          Comment


          • #6
            You set the release-strategy-expression to 'true' instead of 'size() == 2' as in the sample so, of course, the aggregator releases immediately, rather than waiting for the response.

            Comment


            • #7
              When I change to that expression, its waits forever and doesn't return anything, I dont know where is the place SI execute something like that: result = InpSocket.readLine();

              Comment


              • #8
                I have even change the config like that ( I suppose early config should be correct ):


                Code:
                 <bean id="serializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer" />
                 	
                   	
                 <int-ip:tcp-connection-factory id="client"
                    type="client"
                    host="192.168.1.2"
                    port="8001"
                    single-use="false"
                    so-timeout="3000"
                    using-nio="false"	
                    deserializer="serializer" 
                  />
                  
                
                 <int:gateway id="gw"
                        service-interface="com.TestingXXX"
                        default-request-channel="input" 
                        default-reply-channel="reply"
                        error-channel="exceptionTransformationChannel" default-reply-timeout="2000" />
                 
                 <bean id="errorTransformer"
                		  class="com.ErrorTransformerXXX" />
                 
                 <int:transformer input-channel="exceptionTransformationChannel"
                        ref="errorTransformer" method="show" />
                        
                   <int:channel id="reply"  datatype="java.lang.String" />
                  
                   <int:channel id="exceptionTransformationChannel" />
                   
                
                    <int-ip:tcp-outbound-gateway id="outGateway"
                	    request-channel="input"
                	    reply-channel="reply"
                	    connection-factory="client"
                	    request-timeout="3000"
                	    reply-timeout="3000" 
                    />
                
                   <int:publish-subscribe-channel id="input" datatype="java.lang.String"/>


                but reading log shows ( Available to read:0 ):


                17:21:49,777|DEBUG||org.springframework.integratio n.ip.tcp.TcpOutboundGateway|trying semaphore
                17:21:49,777|DEBUG||org.springframework.integratio n.ip.tcp.TcpOutboundGateway|got semaphore
                17:21:49,777|DEBUG||org.springframework.integratio n.ip.tcp.connection.TcpNetClientConnectionFactory| Opening new socket connection to 192.168.1.2:8001
                17:21:49,813|DEBUG||org.springframework.integratio n.ip.tcp.connection.TcpNetConnection|Reading...
                17:21:49,814|DEBUG||org.springframework.integratio n.ip.tcp.serializer.ByteArrayCrLfSerializer|Availa ble to read:0
                17:21:49,815|DEBUG||org.springframework.integratio n.ip.tcp.TcpOutboundGateway|Added 192.168.1.2:8001:021c326e-d199-44fb-98b3-33f36df9d624
                17:21:49,815|DEBUG||org.springframework.integratio n.ip.tcp.connection.TcpNetConnection|Message sent [Payload=MESSAGESAMPLExxxxxxx
                ][Headers={timestamp=1353363709777, id=2d01e96d-44c0-4a71-b222-cc5dcefd0443, errorChannel=org.springframework.integration.core. MessagingTemplate$TemporaryReplyChannel@5629040f, replyChannel=org.springframework.integration.core. MessagingTemplate$TemporaryReplyChannel@5629040f}]
                17:21:49,816|DEBUG||org.springframework.integratio n.ip.tcp.serializer.ByteArrayCrLfSerializer|Socket closed during message assembly
                17:21:49,816|DEBUG||org.springframework.integratio n.ip.tcp.connection.TcpNetConnection|Read exception 192.168.1.2:8001:021c326e-d199-44fb-98b3-33f36df9d624 IOException:null:Socket closed during message assembly
                17:21:52,816|DEBUG||org.springframework.integratio n.ip.tcp.TcpOutboundGateway|released semaphore
                17:21:52,818|WARN||org.springframework.integration .gateway.GatewayProxyFactoryBean$MethodInvocationG ateway|failure occurred in gateway sendAndReceive
                org.springframework.integration.MessageTimeoutExce ption: Timed out waiting for response



                I dont understand the reason because the port returns value in 0.3 seconds ( I think dont need wait longer). Now, I dont know how to get the result with SI, help me please.



                the code of ws is like that:

                Code:
                @Endpoint
                public class WSxxx {
                
                	.....	 
                      @Autowired
                 	TestingXXX gw;
                 	
                	
                	 @PayloadRoot(namespace = NAMESPACE_URI, localPart = REQUEST_LOCAL_NAME)
                	 @ResponsePayload
                	 public DataResponseprocessRequest(@RequestPayload DataRequest dataRequest)               
                	      throws Exception {
                	     
                		....
                		 String result = "";
                		 
                	         try {
                	
                			 result = gw.send("MESSAGESAMPLExxxxxxx\n"); // is it correct get the value like that?	 
                		 
                			
                		 } catch(Exception ex) {
                				log.error("ERROR", ex);
                			}
                		
                                 .....
                		.....
                	    
                	 }

                Comment


                • #9
                  Well, for a start, you are using ByteArrayCrLfSerializer which expects the data to be delimited by "\r\n"; looks like you only need \n; we currently don't have a standard (de)serializer for that format. You need a custom (de)serializer. You can base it on the crlf serializer (or even the stxetx serializer, which might be easier - just drop the code that looks for the stx and replace the code looking for the ETX with some that looks for \n.

                  If you are receiving data that ends with just \n, the deserialization will wait until the socket times out (if it has a timeout) or forever otherwise.

                  Comment


                  • #10
                    I forgot to mention that the upcoming 2.2 release has a ByteArrayLfSerializer included: https://github.com/garyrussell/sprin...erializer.java

                    Comment


                    • #11
                      thks a lot!!

                      Comment

                      Working...
                      X