2014-10-28 2 views
1

사람은 스프링을 사용하여 TCP-인바운드 채널 어댑터 클라이언트 예제의 간단한 예를 알고 있나요? 짧은 String을 서버에 보내고 응답으로 단 하나의 바이트 만 받고 소켓을 닫는 간단한 TCP 클라이언트를 만들고 싶습니다.스프링 통합 tcp-inbound-channel-adapter 예제가 있습니까?

<int-ip:tcp-connection-factory id="client2" type="client" 
    host="localhost" port="${availableServerSocket}" single-use="true" 
    so-timeout="10000" deserializer="climaxDeserializer" 
    so-keep-alive="false" /> 

<int:service-activator input-channel="clientBytes2StringChannel" 
    method="valaszjott" ref="echoService"> 
</int:service-activator> 

<int:gateway 
    service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway" 
    id="gw2" default-request-channel="gwchannel"> 
</int:gateway> 
<int:channel id="gwchannel"></int:channel> 
<int:object-to-string-transformer input-channel="gwchannel" 
    id="clientbyte2string" output-channel="outputchannel"> 
</int:object-to-string-transformer> 
<int:channel id="outputchannel"></int:channel> 
<int-ip:tcp-outbound-channel-adapter channel="outputchannel" 
    id="clientoutboundadapter" connection-factory="client2"> 
</int-ip:tcp-outbound-channel-adapter> 
<int-ip:tcp-inbound-channel-adapter id="clientinboundadapter" 
    channel="inputchannel" connection-factory="client2" /> 
<int:channel id="inputchannel"></int:channel> 
<int:service-activator ref="echoService" method="valaszjott" 
    input-channel="inputchannel" id="sa2"> 
</int:service-activator> 

그래서, 내가 내 주요 방법에서이 방법을 사용합니다 :

.... 
SimpleGateway gateway = (SimpleGateway) context.getBean("gw2"); 
String result = gateway.send("foo"); 
.... 

그리고 이에 클라이언트가 서버에 "foo" + /r/n를 전송 여기 내 빈 정의입니다. 서버 측에 나는이 메시지 및 클라이언트 단 하나의 바이트 서버가 응답 /r/n없이 (06H)를 얻을. 클라이언트는 그것을 수신하고 디시리얼라이저는 그것을 찾습니다. 여기 내 디시리얼라이저 클래스입니다 :

@Component("climaxDeserializer")public class ClimaxDeserializer implements 
Deserializer<Integer>{ 
    public Integer deserialize(InputStream arg0) throws IOException { 
     int ertek; 
     do{ 
      ertek = arg0.read(); 
      if (ertek == 6){ 
       System.out.println("We have the ack byte !"); 
       return 1; 
      } 
     } while(ertek >= 0); 
     return null; 
    } 
} 

디시리얼라이저는 ACK 바이트를 발견, 그리고 방법은 값이 1 이 방법의 서비스 활성제 포인트입니다, 정수를 반환이에서

public String valaszjott (int success){ 
     System.out.println("Answer: " + success); 
     if (success == 1){ 
      return "OK"; 
     } else { 
      return "NOK"; 
     } 
    } 

모든 일이 잘 작동하고 valaszjott 방법은 Answer: 1를 출력 가리 킵니다. 그러나합니다 (main 방법)을 결과 매개 변수는 OK 또는 NOK 문자열 값을 얻을 것입니다 결코, 소켓은 열린 상태로 유지됩니다.

는 어디에서 실수를 했습니까? tcp-inbound-channel-adaptertcp-outbound-channel-adapter 쌍을 tcp-outbound-gateway으로 변경하면 ...

답변

1

실수는 multi-threading에 있습니다.

<int:gateway> 호출은 하나의 스레드에 있지만, <int-ip:tcp-inbound-channel-adapter>message-driven 구성 요소이며 스레드 자체의 소켓에 대한 수신기입니다. 그리고 당신은 당신의 게이트웨이 여부를 호출하는 경우는 문제가되지 않습니다 마지막 하나 : 서버 쪽은 항상 소켓에 패킷을 보낼 수 있으며, 어댑터 그들을 받게됩니다.

ack 사용 사례의 경우 <tcp-outbound-gateway>이 가장 좋은 해결책입니다. 그 이유는 요청과 응답 사이에 실제로 correlation이 있기 때문입니다. 그리고 당신은 여러 동시 요청으로 이득을 얻습니다.

<tcp-outbound-channel-adapter><tcp-inbound-channel-adapter>과 마찬가지로 요청이 전송 된 것과 동일한 순서로 응답이 서버에서 반환된다는 보장은 없습니다.

어쨌든 현재의 해결책에서 gateway은 답장을 알지 못하며 마지막 메시지는 요청 메시지 헤더에서 replyChannel으로 전달할 수 없습니다.

<int-ip:tcp-connection-factory>에있는 cached이기 때문에 다른 쪽 소켓에서 닫히지 않습니다.

HTH

+0

감사합니다. –