18
18
19
19
import java .io .IOException ;
20
20
import java .nio .ByteBuffer ;
21
+ import java .util .concurrent .TimeUnit ;
21
22
22
23
import static io .reactivesocket .aeron .Constants .CLIENT_STREAM_ID ;
23
24
import static io .reactivesocket .aeron .Constants .SERVER_STREAM_ID ;
@@ -30,7 +31,7 @@ public class ReactiveSocketAeronServer implements AutoCloseable {
30
31
31
32
private final int port ;
32
33
33
- private final Int2ObjectHashMap <AeronServerDuplexConnection > connections ;
34
+ private volatile Int2ObjectHashMap <AeronServerDuplexConnection > connections ;
34
35
35
36
private final Scheduler .Worker worker ;
36
37
@@ -78,7 +79,7 @@ void poll(FragmentAssembler fragmentAssembler) {
78
79
void fragmentHandler (DirectBuffer buffer , int offset , int length , Header header ) {
79
80
final int sessionId = header .sessionId ();
80
81
81
- int messageTypeInt = buffer .getInt (0 );
82
+ int messageTypeInt = buffer .getInt (offset );
82
83
MessageType type = MessageType .from (messageTypeInt );
83
84
84
85
if (MessageType .FRAME == type ) {
@@ -88,26 +89,39 @@ void fragmentHandler(DirectBuffer buffer, int offset, int length, Header header)
88
89
if (connection != null ) {
89
90
final PublishSubject <Frame > subject = connection .getSubject ();
90
91
ByteBuffer bytes = ByteBuffer .allocate (buffer .capacity ());
91
- buffer .getBytes (BitUtil .SIZE_OF_INT , bytes , buffer .capacity ());
92
+ buffer .getBytes (BitUtil .SIZE_OF_INT + offset , bytes , buffer .capacity ());
92
93
final Frame frame = Frame .from (bytes );
93
94
subject .onNext (frame );
94
95
}
95
96
} else if (MessageType .ESTABLISH_CONNECTION_REQUEST == type ) {
96
- AeronServerDuplexConnection connection = connections .get (sessionId );
97
- connection .establishConnection ();
97
+ final long start = System .nanoTime ();
98
+ AeronServerDuplexConnection connection = null ;
99
+ System .out .println ("Looking a connection to ack establish connection for session id => " + sessionId );
100
+ while (connection == null ) {
101
+ final long current = System .nanoTime ();
102
+
103
+ if (current - start > TimeUnit .SECONDS .toNanos (30 )) {
104
+ throw new RuntimeException ("unable to find connection to ack establish connection for session id => " + sessionId );
105
+ }
106
+
107
+ connection = connections .get (sessionId );
108
+ }
109
+ System .out .println ("Found a connection to ack establish connection for session id => " + sessionId );
110
+ connection .ackEstablishConnection (sessionId );
98
111
}
99
112
100
113
}
101
114
102
115
void newImageHandler (Image image , String channel , int streamId , int sessionId , long joiningPosition , String sourceIdentity ) {
103
- System .out .println (String .format ("Handling new image for session id => %d and stream id => %d" , streamId , sessionId ));
104
116
if (SERVER_STREAM_ID == streamId ) {
117
+ System .out .println (String .format ("Handling new image for session id => %d and stream id => %d" , streamId , sessionId ));
105
118
final AeronServerDuplexConnection connection = connections .computeIfAbsent (sessionId , (_s ) -> {
106
119
final String responseChannel = "udp://" + sourceIdentity .substring (0 , sourceIdentity .indexOf (':' )) + ":" + port ;
107
120
Publication publication = aeron .addPublication (responseChannel , CLIENT_STREAM_ID );
108
121
System .out .println (String .format ("Creating new connection for responseChannel => %s, streamId => %d, and sessionId => %d" , responseChannel , streamId , sessionId ));
109
122
return new AeronServerDuplexConnection (publication );
110
123
});
124
+ System .out .println ("Accepting ReactiveSocket connection" );
111
125
rsServerProtocol .acceptConnection (connection );
112
126
} else {
113
127
System .out .println ("Unsupported stream id " + streamId );
0 commit comments