Я пишу клиент-серверное приложение на основе конечных точек int-ip: tcp. Код написан на Kotlin.
Приложение содержит два клиента tcp, которые должны устанавливать соединение с сервером в определенной последовательности,
один за другим, когда первая очистка уже установила соединение с сервером и произвела некоторую инициализацию.
В качестве решения для этой синхронизации я предполагаю использовать SmartLifecycleRoleController
для запуска группы конечных точек зависимого tcp-клиента.
Для этого в зависимом (втором) клиенте я добавляю атрибуты role="rcCluster"
и auto-startup="false"
в tcp-outbound-channel-adapter и tcp-inbound-channel-adapter
<int-ip:tcp-connection-factory id="rcClientConnectionFactory"
type="client"
host="${tdirelay.host}"
port="${tdirelay.rcPort}"
single-use="false"
so-timeout="10000"
so-keep-alive="false"
serializer="rawSerializerDeserializer"
deserializer="rawSerializerDeserializer"
ssl-context-support="sslContext"/>
<int-ip:tcp-outbound-channel-adapter id="rcOutBoundAdapter"
channel="rcPacketQueueChannel"
phase="5000"
connection-factory="rcClientConnectionFactory"
role="rcCluster"
auto-startup="false"
/>
<int-ip:tcp-inbound-channel-adapter id="rcInboundAdapter"
channel="rcFromServer"
client-mode="true"
retry-interval="5000"
connection-factory="rcClientConnectionFactory"
role="rcCluster"
auto-startup="false"
/>
Ведущий (первый) tcp-клиент использует конечную точку перехватчика для обмена прологом с сервером в соответствии с протоколом:
<bean id="dcInterceptorFactoryChain"
class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
<property name="interceptors">
<array>
<bean class="com.tcpclient.DirectCannel.DCConnectionInterceptorFactory">
</bean>
</array>
</property>
</bean>
<int-ip:tcp-connection-factory id="dcClientConnectionFactory"
type="client"
host="${tdirelay.host}"
port="${tdirelay.dcPort}"
single-use="false"
so-timeout="10000"
so-keep-alive="false"
interceptor-factory-chain="dcInterceptorFactoryChain"
serializer="rawSerializerDeserializer"
deserializer="rawSerializerDeserializer"
ssl-context-support="sslContext"
/>
Я планирую вызвать startLifecyclesInRole(String role)
и stopLifecyclesInRole(String role)
методы SmartLifecycleRoleController
внутри моего класса Interceptor.
Итак, я добавил @Autowired private val roleController: SmartLifecycleRoleController в InterceptorFactory, как объяснено в spring -gration / docs
Мой завод-перехватчик:
class DCConnectionInterceptorFactory() : TcpConnectionInterceptorFactory, ApplicationEventPublisherAware {
@Autowired
private val roleController: SmartLifecycleRoleController? = null
@Volatile
private var applicationEventPublisher: ApplicationEventPublisher? = null
override fun setApplicationEventPublisher(applicationEventPublisher: ApplicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher
}
override fun getInterceptor(): TcpConnectionInterceptorSupport {
return DCConnectionInterceptor(this.applicationEventPublisher!!, roleController!!)
}
}
IntelliJ IDEA выдает предупреждение:
Не удалось автопровода. Не найдено бобов типа «SmartLifecycleRoleController»
И здание дает ошибку:
[task-scheduler-2] ОШИБКА org.springframework.integration.ip.tcp.connection.ClientModeConnectionManager - Не удалось установить соединение с помощью dcClientConnectionFactory, host = localhost, port = 9001
kotlin.KotlinNullPointerException
at com.tcpclient.DirectCannel.DCConnectionInterceptorFactory.getInterceptor (DCConnectionInterceptorFactory.kt: 25)
Полагаю, мне нужно определить bean-компонент типа SmartLifecycleRoleController в файле конфигурации xml
(это не упоминается в документации: https://docs.spring.io/spring-integration/docs/4.3.4.RELEASE/reference/html/messaging-endpoints-chapter.html#endpoint-roles).
Конструктор этого класса имеет аргументы:
public SmartLifecycleRoleController (список ролей, список жизненных циклов)
который я не знаю, как заполнить мое дело в XML-файле:
Если вы знаете, как это сделать, приведите пример использования bean-компонента класса SmartLifecycleRoleController
в файле конфигурации xml.