2
2
3
3
import io .reactivesocket .DuplexConnection ;
4
4
import io .reactivesocket .Frame ;
5
- import io .reactivesocket .ReactiveSocketClientProtocol ;
5
+ import io .reactivesocket .ReactiveSocket ;
6
6
import org .reactivestreams .Publisher ;
7
7
import rx .Observable ;
8
8
import rx .RxReactiveStreams ;
@@ -39,10 +39,12 @@ public class ReactivesocketAeronClient {
39
39
40
40
private static final Int2ObjectHashMap <CountDownLatch > establishConnectionLatches = new Int2ObjectHashMap <>();
41
41
42
- private final ReactiveSocketClientProtocol rsClientProtocol ;
42
+ private ReactiveSocket rsClientProtocol ;
43
43
44
44
private final Aeron aeron ;
45
45
46
+ private final Publication publication ;
47
+
46
48
private volatile boolean running = true ;
47
49
48
50
private final int port ;
@@ -57,12 +59,8 @@ private ReactivesocketAeronClient(String host, int port) {
57
59
58
60
System .out .println ("Creating a publication to channel => " + channel );
59
61
60
- final Publication publication = aeron .addPublication (channel , SERVER_STREAM_ID );
61
-
62
+ publication = aeron .addPublication (channel , SERVER_STREAM_ID );
62
63
final int sessionId = publication .sessionId ();
63
-
64
- subjects .computeIfAbsent (sessionId , (_p ) -> PublishSubject .create ());
65
-
66
64
subscriptions .computeIfAbsent (port , (_p ) -> {
67
65
Subscription subscription = aeron .addSubscription (channel , CLIENT_STREAM_ID );
68
66
@@ -75,44 +73,6 @@ private ReactivesocketAeronClient(String host, int port) {
75
73
76
74
establishConnection (publication , sessionId );
77
75
78
- this .rsClientProtocol =
79
- ReactiveSocketClientProtocol .create (new DuplexConnection () {
80
-
81
- public Publisher <Frame > getInput () {
82
- PublishSubject publishSubject = subjects .get (sessionId );
83
- return RxReactiveStreams .toPublisher (publishSubject );
84
- }
85
-
86
- @ Override
87
- public Publisher <Void > write (Publisher <Frame > o ) {
88
- Observable <Void > req = RxReactiveStreams
89
- .toObservable (o )
90
- .map (frame -> {
91
- final ByteBuffer frameBuffer = frame .getByteBuffer ();
92
- final int frameBufferLength = frameBuffer .capacity ();
93
- final UnsafeBuffer buffer = buffers .get ();
94
- final byte [] bytes = new byte [frameBufferLength + BitUtil .SIZE_OF_INT ];
95
-
96
- buffer .wrap (bytes );
97
- buffer .putInt (0 , MessageType .FRAME .getEncodedType ());
98
- buffer .putBytes (BitUtil .SIZE_OF_INT , frameBuffer , frameBufferLength );
99
-
100
- for (;;) {
101
- final long offer = publication .offer (buffer );
102
-
103
- if (offer >= 0 ) {
104
- break ;
105
- } else if (Publication .NOT_CONNECTED == offer ) {
106
- throw new RuntimeException ("not connected" );
107
- }
108
- }
109
-
110
- return null ;
111
- });
112
-
113
- return RxReactiveStreams .toPublisher (req );
114
- }
115
- });
116
76
}
117
77
118
78
public static ReactivesocketAeronClient create (String host , int port ) {
@@ -128,15 +88,58 @@ void fragmentHandler(DirectBuffer buffer, int offset, int length, Header header)
128
88
MessageType messageType = MessageType .from (messageTypeInt );
129
89
if (messageType == MessageType .FRAME ) {
130
90
final PublishSubject <Frame > subject = subjects .get (header .sessionId ());
131
- ByteBuffer bytes = ByteBuffer .allocate (buffer . capacity () );
132
- buffer .getBytes (BitUtil .SIZE_OF_INT , bytes , buffer . capacity () );
91
+ ByteBuffer bytes = ByteBuffer .allocate (length );
92
+ buffer .getBytes (BitUtil .SIZE_OF_INT + offset , bytes , length );
133
93
final Frame frame = Frame .from (bytes );
134
94
subject .onNext (frame );
135
95
} else if (messageType == MessageType .ESTABLISH_CONNECTION_RESPONSE ) {
136
96
int ackSessionId = buffer .getInt (offset + BitUtil .SIZE_OF_INT );
137
97
System .out .println (String .format ("Received establish connection ack for session id => %d" , ackSessionId ));
98
+
99
+ subjects .computeIfAbsent (header .sessionId (), (_p ) -> PublishSubject .create ());
100
+
101
+ this .rsClientProtocol =
102
+ ReactiveSocket .connect (new DuplexConnection () {
103
+
104
+ public Publisher <Frame > getInput () {
105
+ PublishSubject publishSubject = subjects .get (header .sessionId ());
106
+ return RxReactiveStreams .toPublisher (publishSubject );
107
+ }
108
+
109
+ @ Override
110
+ public Publisher <Void > write (Publisher <Frame > o ) {
111
+ Observable <Void > req = RxReactiveStreams
112
+ .toObservable (o )
113
+ .flatMap (frame -> {
114
+ final ByteBuffer frameBuffer = frame .getByteBuffer ();
115
+ final int frameBufferLength = frameBuffer .capacity ();
116
+ final UnsafeBuffer buffer = buffers .get ();
117
+ final byte [] bytes = new byte [frameBufferLength + BitUtil .SIZE_OF_INT ];
118
+
119
+ buffer .wrap (bytes );
120
+ buffer .putInt (0 , MessageType .FRAME .getEncodedType ());
121
+ buffer .putBytes (BitUtil .SIZE_OF_INT , frameBuffer , frameBufferLength );
122
+
123
+ for (; ; ) {
124
+ final long offer = publication .offer (buffer );
125
+
126
+ if (offer >= 0 ) {
127
+ break ;
128
+ } else if (Publication .NOT_CONNECTED == offer ) {
129
+ Observable .error (new RuntimeException ("not connected" ));
130
+ }
131
+ }
132
+
133
+ return Observable .empty ();
134
+ });
135
+
136
+ return RxReactiveStreams .toPublisher (req );
137
+ }
138
+ });
139
+
138
140
CountDownLatch latch = establishConnectionLatches .get (ackSessionId );
139
141
latch .countDown ();
142
+
140
143
} else {
141
144
System .out .println ("Unknow message type => " + messageTypeInt );
142
145
}
@@ -189,20 +192,23 @@ void establishConnection(final Publication publication, final int sessionId) {
189
192
190
193
}
191
194
192
- public Publisher <String > requestResponse (String payload ) {
193
- return rsClientProtocol .requestResponse (payload );
195
+ public Publisher <String > requestResponse (String data , String metadata ) {
196
+ return rsClientProtocol .requestResponse (data , metadata );
194
197
}
195
198
196
- public Publisher <String > requestStream (String payload ) {
197
- return rsClientProtocol .requestStream ( payload );
199
+ public Publisher <Void > fireAndForget (String data , String metadata ) {
200
+ return rsClientProtocol .fireAndForget ( data , metadata );
198
201
}
199
202
200
- public Publisher <Void > fireAndForget (String payload ) {
201
- return rsClientProtocol .fireAndForget ( payload );
203
+ public Publisher <String > requestStream (String data , String metadata ) {
204
+ return rsClientProtocol .requestStream ( data , metadata );
202
205
}
203
206
204
- public Publisher <String > requestSubscription (String payload ) {
205
- return rsClientProtocol .requestSubscription (payload );
207
+ public Publisher <String > requestSubscription (String data , String metadata ) {
208
+ return rsClientProtocol .requestSubscription (data , metadata );
206
209
}
207
210
211
+ public Publisher <Void > responderPublisher () {
212
+ return rsClientProtocol .responderPublisher ();
213
+ }
208
214
}
0 commit comments