17
17
18
18
import com .rabbitmq .client .AMQP ;
19
19
import com .rabbitmq .client .Address ;
20
+ import com .rabbitmq .client .MalformedFrameException ;
20
21
import com .rabbitmq .client .SocketConfigurator ;
21
22
import org .slf4j .Logger ;
22
23
import org .slf4j .LoggerFactory ;
@@ -127,9 +128,12 @@ public void run() {
127
128
Selector selector = state .selector ;
128
129
// FIXME find a better default?
129
130
ByteBuffer buffer = ByteBuffer .allocate (8192 );
130
-
131
131
try {
132
132
while (true ) {
133
+ int select = selector .select ();
134
+
135
+ // registrations should be done after select,
136
+ // once the cancelled keys have been actually removed
133
137
RegistrationState registration ;
134
138
while ((registration = state .statesToBeRegistered .poll ()) != null ) {
135
139
int operations = registration .operations ;
@@ -139,7 +143,6 @@ public void run() {
139
143
registration .done ();
140
144
}
141
145
142
- int select = selector .select ();
143
146
if (select > 0 ) {
144
147
Set <SelectionKey > readyKeys = selector .selectedKeys ();
145
148
Iterator <SelectionKey > iterator = readyKeys .iterator ();
@@ -150,12 +153,102 @@ public void run() {
150
153
SocketChannel channel = (SocketChannel ) key .channel ();
151
154
if (key .isReadable ()) {
152
155
SocketChannelFrameHandlerState state = (SocketChannelFrameHandlerState ) key .attachment ();
156
+
153
157
channel .read (buffer );
154
158
buffer .flip ();
155
159
// FIXME handle partial frame
156
160
while (buffer .hasRemaining ()) {
157
- Frame frame = Frame .readFrom (channel , buffer );
161
+ // FIXME make frame read better
162
+ int type ;
163
+ int channelHeader ;
164
+
165
+ if (!buffer .hasRemaining ()) {
166
+ buffer .clear ();
167
+ channel .read (buffer );
168
+ buffer .flip ();
169
+ }
170
+
171
+ type = buffer .get () & 0xff ;
172
+
173
+ if (!buffer .hasRemaining ()) {
174
+ buffer .clear ();
175
+ channel .read (buffer );
176
+ buffer .flip ();
177
+ }
178
+
179
+ int ch1 = buffer .get () & 0xff ;
180
+
181
+
182
+ if (!buffer .hasRemaining ()) {
183
+ buffer .clear ();
184
+ channel .read (buffer );
185
+ buffer .flip ();
186
+ }
187
+ int ch2 = buffer .get () & 0xff ;
188
+
189
+ channelHeader = (ch1 << 8 ) + (ch2 << 0 );
190
+
191
+ if (!buffer .hasRemaining ()) {
192
+ buffer .clear ();
193
+ channel .read (buffer );
194
+ buffer .flip ();
195
+ }
196
+ byte b3 = buffer .get ();
197
+ if (!buffer .hasRemaining ()) {
198
+ buffer .clear ();
199
+ channel .read (buffer );
200
+ buffer .flip ();
201
+ }
202
+ byte b2 = buffer .get ();
203
+ if (!buffer .hasRemaining ()) {
204
+ buffer .clear ();
205
+ channel .read (buffer );
206
+ buffer .flip ();
207
+ }
208
+ byte b1 = buffer .get ();
209
+ if (!buffer .hasRemaining ()) {
210
+ buffer .clear ();
211
+ channel .read (buffer );
212
+ buffer .flip ();
213
+ }
214
+ byte b0 = buffer .get ();
215
+
216
+ int payloadSize = (((b3 ) << 24 ) |
217
+ ((b2 & 0xff ) << 16 ) |
218
+ ((b1 & 0xff ) << 8 ) |
219
+ ((b0 & 0xff ) ));
220
+
221
+
222
+ byte [] payload = new byte [payloadSize ];
223
+ if (payloadSize > buffer .remaining ()) {
224
+ int remaining = buffer .remaining ();
225
+ buffer .get (payload , 0 , remaining );
226
+ buffer .clear ();
227
+ channel .read (buffer );
228
+ buffer .flip ();
229
+ buffer .get (payload , remaining , payloadSize - remaining );
230
+ } else {
231
+ buffer .get (payload );
232
+ }
233
+
234
+ if (!buffer .hasRemaining ()) {
235
+ buffer .clear ();
236
+ channel .read (buffer );
237
+ buffer .flip ();
238
+ }
239
+ int frameEndMarker = buffer .get () & 0xff ;
240
+ if (frameEndMarker != AMQP .FRAME_END ) {
241
+ throw new MalformedFrameException ("Bad frame end marker: " + frameEndMarker );
242
+ }
243
+ Frame frame = new Frame (type , channelHeader , payload );
158
244
state .addReadFrame (frame );
245
+
246
+ if (!buffer .hasRemaining ()) {
247
+ buffer .clear ();
248
+ channel .read (buffer );
249
+ buffer .flip ();
250
+ }
251
+
159
252
}
160
253
buffer .clear ();
161
254
}
@@ -165,9 +258,7 @@ public void run() {
165
258
} catch (Exception e ) {
166
259
LOGGER .error ("Error in read loop" , e );
167
260
}
168
-
169
261
}
170
-
171
262
}
172
263
173
264
private static class WriteLoop implements Runnable {
@@ -186,16 +277,18 @@ public void run() {
186
277
187
278
try {
188
279
while (true ) {
280
+ int select = selector .select ();
281
+
282
+ // registrations should be done after select,
283
+ // once the cancelled keys have been actually removed
189
284
RegistrationState registration ;
190
285
while ((registration = state .statesToBeRegistered .poll ()) != null ) {
191
286
int operations = registration .operations ;
192
287
SelectionKey writeKey = registration .state .getChannel ().register (selector , operations );
193
288
writeKey .attach (registration .state );
194
- registration .state .setWriteSelectionKey (writeKey );
195
289
registration .done ();
196
290
}
197
291
198
- int select = selector .select ();
199
292
if (select > 0 ) {
200
293
Set <SelectionKey > readyKeys = selector .selectedKeys ();
201
294
Iterator <SelectionKey > iterator = readyKeys .iterator ();
0 commit comments