TCPポートでリッスンし、接続を受け入れるサーバーをSpringで作成しようとしています。着信要求をサービスにルーティングする方法を知っており、それらに応答できます。ただし、リクエストを受信せずに特定のクライアントにメッセージを送信するのが好きです。たとえば、メッセージを受信したことをクライアントに通知する必要がある場合があります。
これを行うには、クライアントを識別する方法が必要だと思います。ログインさせることで。ログインデータを保存できるアクティブな接続ごとに「セッション」オブジェクトを作成する方法はありますか?
ユーザー名Xでログインしているクライアントにメッセージを送信するにはどうすればよいですか?
これは春に可能ですか?
バージョン3.0以降。フレームワークが 接続状態が変化すると接続イベントを発行します 。これらのイベントは、ApplicationListener
を使用するか、<event:inbound-channel-adapter/>
を使用してキャプチャできます。
TcpConnectionOpenEvent
にはconnectionId
が含まれています。メッセージにIpHeaders.connectionId
ヘッダー(ip_connectionId
)を入力し、それを<tcp:outbound-channel-adapter/>
に送信することで、IDがわかれば、任意のメッセージを任意の接続に送信できます。
要求/応答と任意のメッセージの送信をサポートする必要がある場合は、ゲートウェイではなく、すべての通信に協調するチャネルアダプタのペアを使用する必要があります。
[〜#〜]編集[〜#〜]
これが簡単なブートアプリです...
package com.example;
import Java.io.BufferedReader;
import Java.io.InputStreamReader;
import Java.net.Socket;
import javax.net.SocketFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.ip.IpHeaders;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.TcpSendingMessageHandler;
import org.springframework.integration.ip.tcp.connection.TcpConnectionOpenEvent;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpServerConnectionFactory;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@SpringBootApplication
public class So25102101Application {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = new SpringApplicationBuilder(So25102101Application.class)
.web(false)
.run(args);
int port = context.getBean(TcpServerConnectionFactory.class).getPort();
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = reader.readLine();
System.out.println(line);
context.close();
}
@Bean
public TcpReceivingChannelAdapter server(TcpNetServerConnectionFactory cf) {
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(cf);
adapter.setOutputChannel(inputChannel());
return adapter;
}
@Bean
public MessageChannel inputChannel() {
return new QueueChannel();
}
@Bean
public MessageChannel outputChannel() {
return new DirectChannel();
}
@Bean
public TcpNetServerConnectionFactory cf() {
return new TcpNetServerConnectionFactory(0);
}
@Bean
public IntegrationFlow outbound() {
return IntegrationFlows.from(outputChannel())
.handle(sender())
.get();
}
@Bean
public MessageHandler sender() {
TcpSendingMessageHandler tcpSendingMessageHandler = new TcpSendingMessageHandler();
tcpSendingMessageHandler.setConnectionFactory(cf());
return tcpSendingMessageHandler;
}
@Bean
public ApplicationListener<TcpConnectionOpenEvent> listener() {
return new ApplicationListener<TcpConnectionOpenEvent>() {
@Override
public void onApplicationEvent(TcpConnectionOpenEvent event) {
outputChannel().send(MessageBuilder.withPayload("foo")
.setHeader(IpHeaders.CONNECTION_ID, event.getConnectionId())
.build());
}
};
}
}
pom deps:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ip</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>