-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathreactor-netty.drawio
1576 lines (1576 loc) · 233 KB
/
reactor-netty.drawio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<mxfile host="Electron" modified="2024-04-25T16:55:07.552Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.5 Chrome/114.0.5735.243 Electron/25.3.1 Safari/537.36" etag="Tb8kNVy5hl6YYDNGPA-O" version="21.6.5" type="device">
<diagram name="第 1 页" id="SFu54w4d0Ybn-GLYL5bF">
<mxGraphModel dx="3712" dy="764" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="uSWqA2PRX45ugPRLn6LA-1" value="<p style="line-height: 1; font-size: 10px;"></p><h1 style="font-size: 16px;"><font style="font-size: 16px;"><font style="font-size: 16px;">Reactor-Netty 工作原理</font><font style="font-size: 16px;">&nbsp;</font><font style="font-size: 16px;">(v0.9.1)&nbsp;<br style=""></font></font></h1><div style=""><font style="font-size: 10px;">结合ProjectReactor将Netty封装成了响应式的通信框架。v0.9.1 基于 Netty-4.1.43。</font></div><p style=""><font style="font-size: 10px;">前提:</font></p><p style="font-size: 10px;"></p><ul style="font-size: 10px;"><li style="font-size: 10px;">熟悉 reactor-core、netty 实现原理和使用 (参考对应流程图)</li></ul><div style="font-size: 10px;">#说明:<br style="font-size: 10px;"><ul style="font-size: 10px;"><li style="font-size: 10px;">这里研究Reactor-Netty是怎么封装Netty和HTTP协议的, 以官方单元测试 HttpServerTests#releaseInboundChannelOnNonKeepAliveRequest() 为例</li></ul></div><p style="font-size: 10px;"></p><p style="font-size: 10px;"></p>" style="text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="10" y="10" width="810" height="150" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-4" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-2" target="uSWqA2PRX45ugPRLn6LA-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-16" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-2" target="uSWqA2PRX45ugPRLn6LA-15" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-2" value="HttpServer 初始化<br><font color="#007fff">返回经多多层装饰后的HttpServer对象</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="40" y="200" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-6" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-3" target="uSWqA2PRX45ugPRLn6LA-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-44" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-3" target="uSWqA2PRX45ugPRLn6LA-43" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-3" value=".create()<br><font color="#007fff">主要是创建TcpServer并设置基本选项</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="200" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-8" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-5" target="uSWqA2PRX45ugPRLn6LA-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-65" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-5" target="uSWqA2PRX45ugPRLn6LA-64" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-5" value=".port(8080)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="360" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-10" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-7" target="uSWqA2PRX45ugPRLn6LA-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-71" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-7" target="uSWqA2PRX45ugPRLn6LA-70" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-7" value=".handle((req, resp) -&gt; req.receive()<br>.then(resp.status(200).send()))<br><font color="#007fff">装配请求处理器方法(请求处理入口)</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="440" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-75" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-9" target="uSWqA2PRX45ugPRLn6LA-74" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-9" value=".wiretap(true)<br><font color="#007fff">开启wire logger<br>由后面的实现可以看到是注册了一个ChannelHandler实现日志记录的<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="520" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-81" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-11" target="uSWqA2PRX45ugPRLn6LA-80" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-11" value=".bindNow()<br><font color="#007fff">返回 DisposableServer 对象</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="722" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-31" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-13" target="bm2imlQ028U47hNO7TBu-30" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-13" value="Mono.when(<br>disposableServer.onDispose())<br>.block();" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="881" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-18" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-15" target="uSWqA2PRX45ugPRLn6LA-17" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-19" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-15" target="uSWqA2PRX45ugPRLn6LA-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-15" value="HttpServer 启动,<br>绑定端口并等待绑定完成" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="40" y="722" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-20" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-17" target="uSWqA2PRX45ugPRLn6LA-13" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-23" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-17" target="bm2imlQ028U47hNO7TBu-22" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-17" value="HttpServer 阻塞等待服务关闭" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="40" y="881" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-21" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.http.server<font style="background-color: initial; font-size: 10px;">.</font></font><b style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;">HttpServer</b></font></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#007fff" style="font-size: 10px;">reator-netty HTTP服务器抽象实现类</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#007fff" style="font-size: 10px;">//核心基于 TcpServer, 这里是默认实现</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">static final TcpServer <b style="font-size: 10px;">DEFAULT_TCP_SERVER</b> = TcpServer.create();</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//下面是 TcpServer 属性配置的函数式方法</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;"><span style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;">static final Function&lt;TcpServer, TcpServer&gt; </span><b style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;">COMPRESS_ATTR_CONFIG</b><span style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;"> = (tcp) -&gt; {</span><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">&nbsp; &nbsp; return tcp.bootstrap(HttpServerConfiguration.MAP_COMPRESS);</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">};</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">static final Function&lt;TcpServer, TcpServer&gt; <b style="font-size: 10px;">COMPRESS_ATTR_DISABLE</b> = (tcp) -&gt; {</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">&nbsp; &nbsp; return tcp.bootstrap(HttpServerConfiguration.MAP_NO_COMPRESS);</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">};</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">static final Function&lt;TcpServer, TcpServer&gt; <b style="font-size: 10px;">FORWARD_ATTR_CONFIG</b> = (tcp) -&gt; {</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">&nbsp; &nbsp; return tcp.bootstrap(HttpServerConfiguration.MAP_FORWARDED);</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">};</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">static final Function&lt;TcpServer, TcpServer&gt; <b style="font-size: 10px;">FORWARD_ATTR_DISABLE</b> = (tcp) -&gt; {</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">&nbsp; &nbsp; return tcp.bootstrap(HttpServerConfiguration.MAP_NO_FORWARDED);</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">};</font></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-960" y="200" width="480" height="260" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-22" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-23" target="uSWqA2PRX45ugPRLn6LA-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-23" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.http.server<font style="background-color: initial; font-size: 10px;">.</font><b style="background-color: initial; font-size: 10px;"><font style="font-size: 10px;">HttpServerBind</font></b></font></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">HttpServer的具体实现,单例模式对象 TcpServerBind.INSTANCE</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">static final HttpServerBind <b style="font-size: 10px;">INSTANCE</b> = new HttpServerBind();</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">static final Function&lt;DisposableServer, DisposableServer&gt; <b style="font-size: 10px;">CLEANUP_GLOBAL_RESOURCE</b> =&nbsp;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><span style="white-space: pre; font-size: 10px;">	</span>DisposableBind::new;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//实际使用的TcpServer对象,如果构造方法没有传参就默认使用 DEFAULT_TCP_SERVER</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final TcpServer <b style="font-size: 10px;">tcpServer</b>;</font></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-960" y="494" width="480" height="126" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-24" style="orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-25" target="uSWqA2PRX45ugPRLn6LA-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-25" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.tcp.</font><span style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;"><b style="font-size: 10px;">TcpServer</b></span></font></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#007fff" style="font-size: 10px;">reactor-netty Tcp服务器抽象实现类</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;">static final int <b style="font-size: 10px;">DEFAULT_PORT</b> = 0;</font><br style="font-size: 10px;"></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000" style="">static final LoggingHandler <b>LOGGING_HANDLER</b> =&nbsp;</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000" style=""><span style="white-space: pre;">	</span>new LoggingHandler(TcpServer.class);<br></font></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-1400" y="200" width="400" height="120" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-26" style="orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-27" target="uSWqA2PRX45ugPRLn6LA-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-27" value="<div style="text-align: center; font-size: 10px;"><font color="#000000" style="font-size: 10px;">reactor.netty.tcp.<b style="font-size: 10px;">Tcp</b></font><b style="font-size: 10px; color: rgb(0, 0, 0); background-color: initial;">ServerBind</b></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">TcpServer的具体实现,单例模式对象TcpServerBind.INSTANCE</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;">同时实现了 Function&lt;ServerBootStrap, ServerBootstrap&gt; 接口,用于定义初始化<br style="font-size: 10px;">方法</p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;">static final TcpServerBind <b style="font-size: 10px;">INSTANCE</b> = new TcpServerBind();</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;">//Netty的服务端实例</p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;"><span style="font-size: 10px;">final <b style="font-size: 10px;">ServerBootstrap</b> <b style="font-size: 10px;">serverBootstrap</b> = this.createServerBootstrap();</span></font></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-1400" y="494" width="400" height="126" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-28" style="orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=none;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-30" target="uSWqA2PRX45ugPRLn6LA-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-29" style="orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-30" target="uSWqA2PRX45ugPRLn6LA-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-30" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.tcp.</font></font><span style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;"><b style="font-size: 10px;">TcpServerOperator</b></span></font></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;">用于通过装饰器模式拓展功能</p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//被装饰的TcpServer实例</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;">final TcpServer source;</font><br style="font-size: 10px;"></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-1780" y="494" width="320" height="105" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-31" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-32" target="uSWqA2PRX45ugPRLn6LA-30" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-32" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.tcp.</font></font></font><span style="background-color: initial; font-size: 10px;"><b style="color: rgb(0, 0, 0); font-size: 10px;">TcpServerBootstrap </b>(这里是<b style="font-size: 10px;">装饰器模式</b>)</span></font></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//用于装配TCP服务器配置的函数式方法,每装饰一层注册一个方法</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final Function&lt;? super ServerBootstrap, ? extends ServerBootstrap&gt; <b>bootstrapMapper</b>;</font><br style="font-size: 10px;"></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-1840" y="641" width="440" height="79" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-33" style="orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-34" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="-720.0000000000005" y="460" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-34" value="<div style="text-align: center; font-size: 10px;"><font color="#000000" style="font-size: 10px;">reactor.netty.http.server.</font><span style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;"><b style="font-size: 10px;">HttpServerOperator</b></span></div><hr style="font-size: 10px;"><p style="border-color: var(--border-color); margin: 0px 0px 0px 4px;"><span style="background-color: initial;">通过</span><b style="background-color: initial;">装饰器模式</b><span style="background-color: initial;">装配上 </span><b style="background-color: initial;">TCP配置</b><span style="background-color: initial;">、</span><b style="background-color: initial;">请求处理器</b><span style="background-color: initial;"> 等组件</span><br></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;"><br></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font color="#000000" style="font-size: 10px;">final HttpServer&nbsp;source; </font><font style="font-size: 10px;">//被装饰的HttpServer实例</font><br style="font-size: 10px;"></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-440" y="494" width="360" height="105" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-35" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-36" target="uSWqA2PRX45ugPRLn6LA-34" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-36" value="<div style="text-align: center; font-size: 10px;"><font color="#000000" style="font-size: 10px;">reactor.netty.http.server</font><font style="background-color: initial; font-size: 10px;"><font color="#000000" style="font-size: 10px;">.</font></font><span style="background-color: initial; font-size: 10px;"><font color="#000000" style="font-size: 10px;"><b style="font-size: 10px;">HttpServerTcpConfig</b></font><b style="color: rgb(0, 0, 0); font-size: 10px;">&nbsp;</b><span style="font-size: 10px;">(</span><b style="font-size: 10px;">装饰器模式</b><span style="font-size: 10px;">)</span></span></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;">用于装配TCP配置信息(比如:端口、wire logger)</p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//设置端口、wire logger等配置的函数方法</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">f</font><span style="color: rgb(0, 0, 0); background-color: initial;">inal Function&lt;? super ServerBootstrap, ? extends ServerBootstrap&gt; <b>bootstrapMapper</b>;</span></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-480" y="660" width="440" height="100" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-39" style="orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;fontSize=10;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-40" target="uSWqA2PRX45ugPRLn6LA-34" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-40" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.http.server</font><font style="background-color: initial; font-size: 10px;"><font style="font-size: 10px;" color="#000000">.</font></font><span style="background-color: initial; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><b style="font-size: 10px;">HttpServerHandle</b></font><b style="color: rgb(0, 0, 0); font-size: 10px;">&nbsp;</b>(<b style="font-size: 10px;">装饰器模式</b>)</span></font></div><hr style="font-size: 10px;">用于装配处理器逻辑<br><br><p style="margin: 0px 0px 0px 4px; font-size: 10px;"></p><font style="font-size: 10px;"><font style="font-size: 10px;">//处理请求的函数方法,它作为业务处理入口</font><span style="font-size: 10px; color: rgb(0, 0, 0); background-color: initial;"><br>final BiFunction&lt;? super HttpServerRequest, ? super</span><br style="font-size: 10px;"></font><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServerResponse, ? extends Publisher&lt;Void&gt;&gt; <b style="font-size: 10px;">handler</b>;</font></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-960" y="661" width="440" height="99" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-41" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.resources</font><font style="background-color: initial; font-size: 10px;" color="#000000">.</font><b style="color: rgb(0, 0, 0); background-color: initial; font-size: 10px;">DefaultLoopResources</b></font></div><hr style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;用于客户端和服务端创建并缓存EventLoopGroup(一组线程)的,<br style="font-size: 10px;">&nbsp;可以当作EventLoopGroup的工厂+管理器</font><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//线程名前缀</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final String&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b style="font-size: 10px;">prefix</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//是否是守护线程</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final boolean&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<b style="font-size: 10px;">daemon</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//selector线程(即boss线程,分发请求)数量</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final int&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<b style="font-size: 10px;">selectCount</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//工作线程(处理请求)数量</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final int&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<b style="font-size: 10px;">workerCount</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//这三组功能同后面的三组EventLoopGroup,只是基于 <b style="font-size: 10px;">NioEventLoopGroup</b></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;"><b style="font-size: 10px;">//后面三组基于 projectreactor DefaultLoopEpoll,</b>不过记得本质都是一样的,底层都是epoll,</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">只是封装不同, 默认用 useNative = true, 即用DefaultLoopEpoll</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicReference&lt;EventLoopGroup&gt; <b style="font-size: 10px;">serverLoops</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicReference&lt;EventLoopGroup&gt; <b style="font-size: 10px;">clientLoops</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicReference&lt;EventLoopGroup&gt; <b style="font-size: 10px;">serverSelectLoops</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//客户端线程组(并不等同于连接线程)</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicReference&lt;EventLoopGroup&gt; <b style="font-size: 10px;">cacheNativeClientLoops</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//服务端worker线程组,默认情况下和boss线程组是同一组线程,</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//调试可以发现和下面的cacheNativeSelectLoops中的线程组是同一个对象</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicReference&lt;EventLoopGroup&gt; <b style="font-size: 10px;">cacheNativeServerLoops</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">//服务端Selector(boss)线程组</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicReference&lt;EventLoopGroup&gt; <b style="font-size: 10px;">cacheNativeSelectLoops</b>;</font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000">final AtomicBoolean&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;running;</font></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-480" y="801" width="440" height="360" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-42" value="<font color="#007fff" style="font-size: 10px;">Reactor-Netty提供了HTTP TCP UDP <br>三种CS实现,这里主要分析HTTP, <br>不过HTTP服务器是基于TCP服务器实现的</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="40" y="260" width="210" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-46" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-43" target="uSWqA2PRX45ugPRLn6LA-45" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-48" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-43" target="uSWqA2PRX45ugPRLn6LA-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-97" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;fillColor=#dae8fc;strokeColor=#6c8ebf;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-47" target="uSWqA2PRX45ugPRLn6LA-93" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="900" y="245" />
<mxPoint x="900" y="737" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-43" value="HttpServerBind INSTANCE = new <b>HttpServerBind</b>();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-45" value="return HttpServerBind.INSTANCE;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-51" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-47" target="uSWqA2PRX45ugPRLn6LA-50" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-53" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-47" target="uSWqA2PRX45ugPRLn6LA-52" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-47" value="TcpServer.create();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="680" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-49" value="HttpServerBind" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="490" y="170" width="100" height="30" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-50" value="return TcpServerBind.INSTANCE;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="680" y="280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-56" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-52" target="uSWqA2PRX45ugPRLn6LA-55" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-52" value="TcpServerBind INSTANCE = new TcpServerBind();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="920" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-54" value="TcpServerBind" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="970" y="170" width="100" height="30" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-58" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-55" target="uSWqA2PRX45ugPRLn6LA-57" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-60" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-55" target="uSWqA2PRX45ugPRLn6LA-59" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-55" value="this.serverBootstrap = createServerBootstrap();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1160" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-62" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-57" target="uSWqA2PRX45ugPRLn6LA-61" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-57" value="BootstrapHandlers.channelOperationFactory(<br>this.<b>serverBootstrap</b>, TcpUtils.<b>TCP_OPS</b>);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1160" y="280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-59" value="<div style="font-size: 9px;"><font style="font-size: 9px;">return new ServerBootstrap()</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">.option(ChannelOption.SO_REUSEADDR, true)</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">.childOption(ChannelOption.AUTO_READ, false)</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">.childOption(ChannelOption.TCP_NODELAY, true)</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">.localAddress(newInetSocketAddress(DEFAULT_PORT));</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=12;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1400" y="200" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-61" value="b.<b>option</b>(OPS_OPTION, opsFactory);<br><font color="#007fff">OPS_OPTION是拓展的选项,并不是Netty本身定义的</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1400" y="280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-63" value="<font color="#007fff" style="font-size: 10px;">这里的选项对应套接字选项,参考UNIX网络编程C7.5<br>SO_REUSEADDR:主要是为了支持已存在连接的情况下重启服务器,其他3种功能参考Markdown文档<br>TCP_NODELAY: 开启会禁止TCP的Nagle算法,确保响应不会因为存在待确认数据(就是响应还没发回就收到新的数据)而出现延迟<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1650" y="200" width="610" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-67" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-64" target="uSWqA2PRX45ugPRLn6LA-66" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-64" value="return tcpConfiguration(tcpServer -&gt; tcpServer.port(port));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-69" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-66" target="uSWqA2PRX45ugPRLn6LA-68" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-66" value="return new <b>HttpServerTcpConfig</b>(this, tcpMapper);<br><font color="#007fff">HttpServerTcpConfig是装配配置方法后的<br>HttpServer</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
<mxGeometry x="680" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-107" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-68" target="uSWqA2PRX45ugPRLn6LA-106" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-68" value="tcpServer.port(port)<br><font color="#007fff">绑定阶段被调用</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="920" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-73" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-70" target="uSWqA2PRX45ugPRLn6LA-72" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-70" value="return new <b>HttpServerHandle</b>(this, handler);<br><b style="border-color: var(--border-color);"><font color="#007fff">HttpServerHandle<span style="background-color: initial; font-weight: normal;">是装配请求处理方法后的</span><br></font></b><div><font color="#007fff">HttpServer</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
<mxGeometry x="440" y="440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-72" value="(req, resp) -&gt; resp.sendNotFound()<br><font color="#007fff">处理请求阶段被调用</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="680" y="440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-77" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-74" target="uSWqA2PRX45ugPRLn6LA-76" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-74" value="<div>return tcpConfiguration(tcpServer -&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; tcpServer.bootstrap(b -&gt; BootstrapHandlers.updateLogSupport(b, LOGGING_HANDLER)));<span style=""></span></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-79" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-76" target="uSWqA2PRX45ugPRLn6LA-78" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-76" value="return new HttpServerTcpConfig(this, tcpMapper);<br><div><font color="#007fff">HttpServerTcpConfig是装配配置方法后的</font></div><div><font color="#007fff">HttpServer,这一步装配了wire logger 函数方法</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
<mxGeometry x="680" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-109" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-78" target="uSWqA2PRX45ugPRLn6LA-108" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-78" value="<div>tcpServer -&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; tcpServer.bootstrap(b -&gt; BootstrapHandlers.updateLogSupport(b, LOGGING_HANDLER))</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="920" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-83" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-80" target="uSWqA2PRX45ugPRLn6LA-82" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-80" value="bindNow(Duration.ofSeconds(45));<br><font color="#007fff">默认绑定超时时间45s</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="722" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-85" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-82" target="uSWqA2PRX45ugPRLn6LA-84" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-94" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-82" target="uSWqA2PRX45ugPRLn6LA-93" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-82" value="bind()<br><font color="#007fff">返回Mono&lt;DisposableServer&gt;对象</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="680" y="722" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-84" value=".block(timeout)<br><font color="#007fff">阻塞等待Mono接收到下一个信号(元素)(</font><font color="#007fff">TcpServerBind#<b>operationComplete</b>()会发送信号</font><font color="#007fff">)</font><font style="border-color: var(--border-color);" color="#007fff">即</font><font style="border-color: var(--border-color);" color="#007fff">等待HttpServer bind 成功或失败</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="680" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-91" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-88" target="uSWqA2PRX45ugPRLn6LA-90" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-88" value="return source.bind(b)<br><font color="#007fff">层层深入最终调用HttpServerBind的bind</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1160" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-112" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-90" target="uSWqA2PRX45ugPRLn6LA-111" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-116" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-90" target="uSWqA2PRX45ugPRLn6LA-115" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-90" value="bootstrap(this)<br><font color="#007fff">装配HttpServerBind#apply()</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1400" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-92" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">HttpServer装配后的实际对象:</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">this = {<b>HttpServerTcpConfig</b>@2224}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;tcpServerMapper = {HttpServer$lambda@2225}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;source = {<b>HttpServerHandle</b>@2226}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; handler = {HttpServerTests$lambda@2218}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; source = {<b>HttpServerTcpConfig</b>@2217}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;tcpServerMapper = {HttpServer$lambda@2219}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;source = {<b>HttpServerBind</b>@2220}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; tcpServer = {TcpServerBind@2180}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp;serverBootstrap = {ServerBootstrap@2182}&nbsp;</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;labelBorderColor=none;labelBackgroundColor=#E6E6E6;" parent="1" vertex="1">
<mxGeometry x="910" y="796" width="250" height="130" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-100" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-93" target="uSWqA2PRX45ugPRLn6LA-99" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-93" value="return bind(tcpConfiguration());" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="920" y="722" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-101" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-99" target="uSWqA2PRX45ugPRLn6LA-78" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1370" y="752" />
<mxPoint x="1370" y="710" />
<mxPoint x="910" y="710" />
<mxPoint x="910" y="565" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-103" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-101" vertex="1" connectable="0">
<mxGeometry x="-0.8832" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-102" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-99" target="uSWqA2PRX45ugPRLn6LA-68" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1390" y="752" />
<mxPoint x="1390" y="510" />
<mxPoint x="910" y="510" />
<mxPoint x="910" y="405" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-104" value="3" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-102" vertex="1" connectable="0">
<mxGeometry x="-0.8751" y="-3" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-105" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-99" target="uSWqA2PRX45ugPRLn6LA-88" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-214" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-99" target="uSWqA2PRX45ugPRLn6LA-72" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1380" y="752" />
<mxPoint x="1380" y="600" />
<mxPoint x="660" y="600" />
<mxPoint x="660" y="485" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-215" value="2" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-214" vertex="1" connectable="0">
<mxGeometry x="-0.8734" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-37" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="uSWqA2PRX45ugPRLn6LA-99" target="uSWqA2PRX45ugPRLn6LA-92" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-99" value="tcpServerMapper.apply(<br>source.tcpConfiguration())<br><font color="#007fff">层层深入调用tcpServerMapper函数式方法<br>对TcpServer进行装配<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="1160" y="722" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-128" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-106" target="uSWqA2PRX45ugPRLn6LA-127" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-106" value="b -&gt; TcpUtils.updatePort(b, port)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1160" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-149" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-108" target="uSWqA2PRX45ugPRLn6LA-148" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-108" value="b -&gt; BootstrapHandlers.updateLogSupport(b, <b>LOGGING_HANDLER</b>)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1160" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-110" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">TcpServer装配后的实际对象:</font></div><div style="font-size: 10px;"><div style=""><font color="#007fff" style="font-size: 10px;">b = {TcpServerBootstrap@2244}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp;bootstrapMapper = {HttpServer$lambda@2245}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp;source = {TcpServerBootstrap@2242}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; bootstrapMapper = {HttpServerHandle@2234}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; source = {TcpServerBootstrap@2232}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;bootstrapMapper = {TcpServer$lambda@2233}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;source = {TcpServerBind@2180}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; serverBootstrap = {ServerBootstrap@2181}&nbsp;</font></div></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;labelBackgroundColor=#E6E6E6;" parent="1" vertex="1">
<mxGeometry x="1160" y="890" width="240" height="120" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-114" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-111" target="uSWqA2PRX45ugPRLn6LA-113" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-118" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-111" target="uSWqA2PRX45ugPRLn6LA-117" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-111" value="bind()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1400" y="881" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-57" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-113" target="bm2imlQ028U47hNO7TBu-56" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-113" value="map(CLEANUP_GLOBAL_RESOURCE)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1400" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-144" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-115" target="uSWqA2PRX45ugPRLn6LA-143" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2140" y="831" />
<mxPoint x="2140" y="470" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-115" value="ServerBootstrap apply(ServerBootstrap b)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1640" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-121" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-117" target="uSWqA2PRX45ugPRLn6LA-120" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-123" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-117" target="uSWqA2PRX45ugPRLn6LA-122" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-117" value="b = configure();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1640" y="881" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-119" value="TcpServer" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1700" y="860" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-176" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-120" target="uSWqA2PRX45ugPRLn6LA-175" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-120" value="return bind(b);<br><font color="#007fff">此时b是经过层层装饰后的TcpServer对象<br>此方法会层层深入执行 TcpServerBind#bind<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1640" y="1040" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-124" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-122" target="uSWqA2PRX45ugPRLn6LA-106" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2100" y="911" />
<mxPoint x="2100" y="430" />
<mxPoint x="1140" y="430" />
<mxPoint x="1140" y="405" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-158" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-124" vertex="1" connectable="0">
<mxGeometry x="-0.5046" y="-3" relative="1" as="geometry">
<mxPoint x="-3" y="22" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-125" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-122" target="uSWqA2PRX45ugPRLn6LA-108" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2100" y="911" />
<mxPoint x="2100" y="590" />
<mxPoint x="1140" y="590" />
<mxPoint x="1140" y="565" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-137" value="3" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-125" vertex="1" connectable="0">
<mxGeometry x="-0.5921" y="-1" relative="1" as="geometry">
<mxPoint x="-21" y="-76" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-126" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-122" target="uSWqA2PRX45ugPRLn6LA-115" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2100" y="911" />
<mxPoint x="2100" y="871" />
<mxPoint x="1620" y="871" />
<mxPoint x="1620" y="846" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-138" value="4" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-126" vertex="1" connectable="0">
<mxGeometry x="-0.7185" y="3" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-132" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-122" target="uSWqA2PRX45ugPRLn6LA-129" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-134" value="2" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uSWqA2PRX45ugPRLn6LA-132" vertex="1" connectable="0">
<mxGeometry x="0.2167" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-38" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="uSWqA2PRX45ugPRLn6LA-122" target="uSWqA2PRX45ugPRLn6LA-110" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-122" value="bootstrapMapper.apply(source.configure()<br><font color="#007fff">一层层地执行 bootstrapMapper, 先克隆TcpServer, 然后配置端口、ConnectionObserver、日志ChannelHandler、线程组、HTTP协议相关</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="1880" y="881" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-127" value="b.<b>localAddress</b>(_updatePort(<br>b.config().localAddress(), port))" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1400" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-131" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-129" target="uSWqA2PRX45ugPRLn6LA-130" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-129" value="HttpServerHandle#apply()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2120" y="881" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-136" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-130" target="uSWqA2PRX45ugPRLn6LA-135" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-140" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-130" target="uSWqA2PRX45ugPRLn6LA-139" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-130" value="ConnectionObserver observer = BootstrapHandlers<br>.<b>childConnectionObserver</b>(b);<br><font color="#007fff">ConnectionObserver 是TCP连接生命周期的监听器</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2360" y="881" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-142" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-135" target="uSWqA2PRX45ugPRLn6LA-141" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-135" value="BootstrapHandlers.childConnectionObserver(<br>b, observer.then(this));<br>return b;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2360" y="961" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-201" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-139" target="uSWqA2PRX45ugPRLn6LA-182" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2580" y="931" />
<mxPoint x="2580" y="1190" />
<mxPoint x="2350" y="1190" />
<mxPoint x="2350" y="1215" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-139" value="<div style="font-size: 8px;"><div>ConnectionObserver obs = (ConnectionObserver) b.config()</div><div>&nbsp; .childOptions()</div><div>&nbsp; .get(<b>OBSERVER_OPTION</b>);</div><div>if (obs == null) {</div><div>&nbsp; &nbsp; return ConnectionObserver.<b>emptyListener</b>();&nbsp;</div><div>}</div><div>b.<b>childOption</b>(<b>OBSERVER_OPTION</b>, null);</div><div>return obs;</div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;align=left;arcSize=8;" parent="1" vertex="1">
<mxGeometry x="2600" y="871" width="220" height="80" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-202" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-141" target="uSWqA2PRX45ugPRLn6LA-182" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2580" y="1006" />
<mxPoint x="2580" y="1190" />
<mxPoint x="2350" y="1190" />
<mxPoint x="2350" y="1215" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-141" value="b.<b>childOption</b>(<b>OBSERVER_OPTION</b>, connectionObserver);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2600" y="961" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-162" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-143" target="uSWqA2PRX45ugPRLn6LA-161" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-143" value="HttpServerConfiguration conf = HttpServerConfiguration.getAndClean(b);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2160" y="440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-151" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-148" target="uSWqA2PRX45ugPRLn6LA-150" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-148" value="c =&nbsp;new <b>LoggingHandlerSupportConsumer</b>(<br>handler, debugSsl);<br>b.<b>childHandler</b>(updateConfiguration(<br>b.config().childHandler(), name, c));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1400" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-156" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-150" target="uSWqA2PRX45ugPRLn6LA-155" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-216" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-217" target="uSWqA2PRX45ugPRLn6LA-209" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2110" y="565" />
<mxPoint x="2110" y="1430" />
<mxPoint x="2340" y="1430" />
<mxPoint x="2340" y="1455" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-218" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-150" target="uSWqA2PRX45ugPRLn6LA-217" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-150" value="<b>BootstrapPipelineHandler</b> p = getOrCreateInitializer(handler);<br><font color="#007fff">初始为空,这里会创建&nbsp;BootstrapPipelineHandler</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1640" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-155" value="p.<b>add</b>(new PipelineConfiguration(c, name));<br><font color="#007fff">注册Pipeline Handler</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1640" y="601" width="200" height="59" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-160" value="BootstrapHandlers" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1440" y="490" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-164" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-161" target="uSWqA2PRX45ugPRLn6LA-163" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-161" value="conf.SSL配置" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2160" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-166" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-163" target="uSWqA2PRX45ugPRLn6LA-165" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-170" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-163" target="uSWqA2PRX45ugPRLn6LA-169" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-163" value="线程组配置" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2160" y="599" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-168" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-165" target="uSWqA2PRX45ugPRLn6LA-167" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-172" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-165" target="uSWqA2PRX45ugPRLn6LA-171" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-165" value="BootstrapHandlers<br>.channelOperationFactory(b);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2160" y="680" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-174" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-167" target="uSWqA2PRX45ugPRLn6LA-173" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-167" value="HTTP协议相关配置<br>协议版本、解码器、压缩、cookie相关<br>支持多种版本协议,这里只关注h11" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2160" y="776" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-169" value="<font style="font-size: 8px;">LoopResources loops = HttpResources.get();<br></font><div style="font-size: 8px;"><font style="font-size: 8px;">EventLoopGroup selector = loops.onServerSelect(LoopResources.DEFAULT_NATIVE);</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">EventLoopGroup elg = loops.onServer(LoopResources.DEFAULT_NATIVE);</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">b.<b>group</b>(selector, elg).<b>channel</b>(loops.onServerChannel(elg));</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=6;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2400" y="589" width="320" height="81" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-171" value="b.option(OPS_OPTION, null);<br>return ops;<br><font color="#007fff">清除自定义选项</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2400" y="680.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-173" value="<div style="font-size: 8px;"><font style="font-size: 8px;">return BootstrapHandlers.<b>updateConfiguration</b>(b,</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; NettyPipeline.HttpInitializer,</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; new Http1Initializer(conf.decoder.maxInitialLineLength(),</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.decoder.maxHeaderSize(),</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.decoder.maxChunkSize(),</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.decoder.validateHeaders(),</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.decoder.initialBufferSize(),</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.minCompressionSize,</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; compressPredicate(conf.compressPredicate, conf.minCompressionSize),</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.forwarded,</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.cookieEncoder,</font></div><div style="font-size: 8px;"><font style="font-size: 8px;">&nbsp; &nbsp; &nbsp; &nbsp; conf.cookieDecoder));</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;arcSize=7;align=left;" parent="1" vertex="1">
<mxGeometry x="2400" y="746" width="320" height="120" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-179" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-175" target="uSWqA2PRX45ugPRLn6LA-178" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-175" value="SSL相关,<br>其实就是往ChannelHandler 责任链中加入了SSL的处理,暂略" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1880" y="1040" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-177" value="TcpServerBind" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1930" y="1018" width="100" height="30" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-181" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;dashed=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-178" target="uSWqA2PRX45ugPRLn6LA-180" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-178" value="return Mono.<b>create</b>(sink-&gt;{...})<br><font color="#007fff">sink -&gt; {} 定义序列生成逻辑,参考reactor-core的流程图</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1880" y="1120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-183" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-180" target="uSWqA2PRX45ugPRLn6LA-182" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-180" value="ServerBootstrap bootstrap = b.clone();<br><font color="#007fff">又克隆了一次,为何不再原对象上操作,<br>哪里会复用么?</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2120" y="1120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-185" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-182" target="uSWqA2PRX45ugPRLn6LA-184" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-204" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-182" target="uSWqA2PRX45ugPRLn6LA-203" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-182" value="<div>ConnectionObserver <b>obs</b> = BootstrapHandlers</div><div>.<b>connectionObserver</b>(bootstrap);</div><div>ConnectionObserver <b>childObs</b> = BootstrapHandlers</div><div>.<b>childConnectionObserver</b>(bootstrap);</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2100" y="1200" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-187" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-184" target="uSWqA2PRX45ugPRLn6LA-186" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-206" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-184" target="uSWqA2PRX45ugPRLn6LA-205" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-184" value="<div>ChannelOperations.OnSetup ops =</div><div>BootstrapHandlers<br>.<b>channelOperationFactory</b>(bootstrap);</div><div><font color="#007fff">创建ChannelOperations工厂</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2120" y="1280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-189" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-186" target="uSWqA2PRX45ugPRLn6LA-188" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-186" value="convertLazyLocalAddress(bootstrap);<br><font color="#007fff">懒配置SocketAddress, 默认没用到,暂略</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2120" y="1360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-191" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-188" target="uSWqA2PRX45ugPRLn6LA-190" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-210" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-188" target="uSWqA2PRX45ugPRLn6LA-209" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-188" value="BootstrapHandlers.<b>finalizeHandler</b>(<br>bootstrap, ops, new ChildObserver(childObs));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="2120" y="1440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-193" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-190" target="uSWqA2PRX45ugPRLn6LA-192" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-190" target="bm2imlQ028U47hNO7TBu-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-190" value="ChannelFuture f = bootstrap.bind();<br><font color="#007fff">Tcp服务器bind</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2120" y="1601" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-195" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-192" target="uSWqA2PRX45ugPRLn6LA-194" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-192" value="DisposableBind disposableServer = new DisposableBind(sink, f, obs, bootstrap);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2120" y="1720" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-197" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-194" target="uSWqA2PRX45ugPRLn6LA-196" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-3" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-194" target="bm2imlQ028U47hNO7TBu-2" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-194" value="f.<b>addListener</b>(disposableServer);<br><font color="#007fff">HttpServer bind成功或失败后会回调 operationComplete() 继承自<b>ChannelFutureListener</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2120" y="1800" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-35" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="uSWqA2PRX45ugPRLn6LA-196" target="bm2imlQ028U47hNO7TBu-34" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-196" value="sink.onCancel(disposableServer);<br><font color="#007fff">注册Mono取消的回调方法,<br>只是用于在Mono取消后调用<b>dispose</b>()释放资源</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2120" y="1938.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-198" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">HttpServer初始化后的实际对象:</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">this = {<b>HttpServerTcpConfig</b>@2224}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;tcpServerMapper = {HttpServer$lambda@2225}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;source = {<b>HttpServerHandle</b>@2226}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; handler = {HttpServerTests$lambda@2218}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; source = {<b>HttpServerTcpConfig</b>@2217}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;tcpServerMapper = {HttpServer$lambda@2219}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;source = {<b>HttpServerBind</b>@2220}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; tcpServer = {TcpServerBind@2180}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp;serverBootstrap = {ServerBootstrap@2182}&nbsp;</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-440" y="350" width="250" height="130" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-199" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">TcpServer装配后的实际对象:</font></div><div style="font-size: 10px;"><div style=""><font color="#007fff" style="font-size: 10px;">b = {TcpServerBootstrap@2244}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp;bootstrapMapper = {HttpServer$lambda@2245}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp;source = {TcpServerBootstrap@2242}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; bootstrapMapper = {HttpServerHandle@2234}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; source = {TcpServerBootstrap@2232}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;bootstrapMapper = {TcpServer$lambda@2233}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;source = {TcpServerBind@2180}&nbsp;</font></div><div style=""><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; serverBootstrap = {ServerBootstrap@2181}&nbsp;</font></div></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-1780" y="360" width="240" height="120" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-200" value="<div style="text-align: center;"><font style=""><font style="font-size: 10px;" color="#000000">reactor.netty.</font><font style="background-color: initial;" color="#000000">channel.</font></font><b style="color: rgb(0, 0, 0); background-color: initial;">BootstrapHandlers</b></div><hr style="font-size: 10px;"><font style="">&nbsp;Helper to update configuration the main {@link Bootstrap} and<span style="background-color: initial;">&nbsp;{@link ServerBootstrap} handlers</span><br><font color="#000000">&nbsp;</font><br>&nbsp;//为 ServerBootStrap 初始化配置 ChannelHandler<br><font color="#000000">&nbsp;public static void finalizeHandler(ServerBootstrap b, ChannelOperations.OnSetup</font><div><span style=""><font color="#000000"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>opsFactory, ConnectionObserver childListener)</font></span></div><span style="background-color: initial;">&nbsp;</span>//为 Bootstrap 即客户端初始化配置 ChannelHandler<div><font color="#000000">&nbsp;public static void finalizeHandler(Bootstrap b,</font></div><div><font color="#000000">&nbsp; &nbsp; ChannelOperations.OnSetup opsFactory, ConnectionObserver listener)</font></div><div><font color="#000000">&nbsp;//</font></div><div><font color="#000000">&nbsp;public static void channelOperationFactory(AbstractBootstrap&lt;?, ?&gt; b,</font></div><div><font color="#000000">&nbsp; &nbsp; ChannelOperations.OnSetup opsFactory)</font></div><div><font color="#000000"><br></font></div><div><font color="#000000">&nbsp;public static ChannelOperations.OnSetup channelOperationFactory(AbstractBootstrap&lt;?, ?&gt; b)</font></div><div><font color="#000000"><br></font></div><div><font color="#000000">&nbsp;public static void connectionObserver(AbstractBootstrap&lt;?, ?&gt; b,</font></div><div><font color="#000000">&nbsp; &nbsp; ConnectionObserver connectionObserver)</font></div><div><font color="#000000"><br></font></div><div><font color="#000000">&nbsp;public static void childConnectionObserver(ServerBootstrap b,</font></div><div><font color="#000000">&nbsp; &nbsp; ConnectionObserver connectionObserver)</font></div><div><font color="#000000"><br></font></div><div><font color="#000000">&nbsp;public static Bootstrap updateConfiguration(Bootstrap b, String name,</font></div><div><font color="#000000">&nbsp; &nbsp; BiConsumer&lt;ConnectionObserver, ? super Channel&gt; c)</font></div><div><font color="#000000"><br></font></div><div><font color="#000000">&nbsp;public static Bootstrap updateLogSupport(Bootstrap b, LoggingHandler handler)</font></div></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-480" y="1200" width="440" height="340" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-203" value="读取AbstractBootstrap选项Map中<br>名为<b>connectionObserver</b>的选项的值" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2360" y="1200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-205" value="ChannelOperations.OnSetup ops = (ChannelOperations.OnSetup) b.config().options().get(<b>OPS_OPTION</b>);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2360" y="1280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-212" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="uSWqA2PRX45ugPRLn6LA-209" target="uSWqA2PRX45ugPRLn6LA-211" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-209" value="<font style="font-size: 9px;">ChannelHandler handler = b.config().<b>childHandler</b>();<br><b>pipeline</b> = (BootstrapPipelineHandler) handler;</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2360" y="1440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-211" value="b.<b>childHandler</b>(new <b>BootstrapInitializerHandler</b>(pipeline, opsFactory, childListener));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2360" y="1520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-213" value="<div style="text-align: center;"><font style=""><font style="font-size: 10px;" color="#000000">reactor.netty.</font><font style="background-color: initial;" color="#000000">channel.</font></font><font style="background-color: initial;" color="#000000"><b>BootstrapHandlers</b></font><font style="background-color: initial;"><font style="background-color: initial;" color="#000000">.</font></font><b style="background-color: initial; color: rgb(0, 0, 0);">BootstrapInitializerHandler&nbsp;</b></div><div style="text-align: center;"><font color="#000000">extends ChannelInitializer&lt;Channel&gt;</font><br></div><hr style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;ChannelHandler pipeline 初始化器</font><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;">// 存储待配置的PipelineConfiguration的List容器</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">final <b>BootstrapPipelineHandler</b> pipeline;</font></p><p style="margin: 0px 0px 0px 4px;">// 连接状态变更的监听器</p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">final ConnectionObserver&nbsp; &nbsp; &nbsp; &nbsp;listener;<span style=""></span></font></p><p style="margin: 0px 0px 0px 4px;">// OPS_OPTION 配置</p><p style="margin: 0px 0px 0px 4px;"><span style=""><font color="#000000">final ChannelOperations.OnSetup opsFactory;</font></span></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-960" y="1200" width="440" height="160" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-217" value="BootstrapPipelineHandler p = new BootstrapPipelineHandler p = <b>BootstrapPipelineHandler</b>(<br>Collections.emptyList());" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1880" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-219" value="<font color="#007fff">将后面创建的 BootstrapPipelineHandler<br>赋值给 ServerBootstrap childHandler<br>&nbsp;</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1400" y="589" width="230" height="60" as="geometry" />
</mxCell>
<mxCell id="uSWqA2PRX45ugPRLn6LA-220" value="<font color="#007fff" style="font-size: 10px;">这里对BootstrapPipelineHandler<br>又注册了 <b>Http1Initializer</b> 这个 Handler<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="2725" y="756" width="200" height="40" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-1" value="<font color="#007fff">MonoCreate 发布者在onSubscribe() <br>触发订阅后,会执行 sink -&gt; {...} 逻辑</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1880" y="1190" width="220" height="40" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-10" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="bm2imlQ028U47hNO7TBu-2" target="bm2imlQ028U47hNO7TBu-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-2" value="TcpServerBind#operationComplete()<br><font color="#007fff">无论成功或失败都会发送信号(序列元素)</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2360" y="1800" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-5" value="<div>f.<b>removeListener</b>(this);</div><div>if (f.channel().isActive()) {</div><div>&nbsp; &nbsp; f.channel().<b>close</b>();</div><div>&nbsp; &nbsp; HttpResources.get().disposeWhen(</div><div>bootstrap.config().localAddress());</div><div>} else if (!f.isDone()) {</div><div>&nbsp; &nbsp; f.<b>cancel</b>(true);</div><div style="">}</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=6;" parent="1" vertex="1">
<mxGeometry x="2600" y="1919" width="200" height="99" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-12" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;rounded=1;" parent="1" source="bm2imlQ028U47hNO7TBu-9" target="bm2imlQ028U47hNO7TBu-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-13" value="失败" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontColor=#007FFF;" parent="bm2imlQ028U47hNO7TBu-12" vertex="1" connectable="0">
<mxGeometry x="-0.25" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-15" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;rounded=1;" parent="1" source="bm2imlQ028U47hNO7TBu-9" target="bm2imlQ028U47hNO7TBu-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-16" value="成功" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontColor=#007FFF;" parent="bm2imlQ028U47hNO7TBu-15" vertex="1" connectable="0">
<mxGeometry x="-0.038" y="-2" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-9" value="!f.isSuccess()" style="rhombus;whiteSpace=wrap;html=1;fontSize=10;rounded=1;" parent="1" vertex="1">
<mxGeometry x="2600" y="1790" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-19" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" source="bm2imlQ028U47hNO7TBu-11" target="uSWqA2PRX45ugPRLn6LA-84" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2940" y="1790" />
<mxPoint x="2940" y="1030" />
<mxPoint x="660" y="1030" />
<mxPoint x="660" y="831" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-11" value="if (f.isCancelled())&nbsp;<br>&nbsp; &nbsp; return;<br>sink.<b>error</b>(ChannelBindException.fail(<br>bootstrap, f.cause()));" style="whiteSpace=wrap;html=1;fontSize=10;rounded=1;align=left;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2720" y="1760" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-18" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#dae8fc;strokeColor=#6c8ebf;rounded=1;" parent="1" source="bm2imlQ028U47hNO7TBu-14" target="uSWqA2PRX45ugPRLn6LA-84" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2940" y="1869" />
<mxPoint x="2940" y="1030" />
<mxPoint x="660" y="1030" />
<mxPoint x="660" y="831" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-21" value="信号" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="bm2imlQ028U47hNO7TBu-18" vertex="1" connectable="0">
<mxGeometry x="0.9705" y="-3" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-14" value="<div>sink.<b>success</b>(this);</div><div>selectorObserver.<b>onStateChange</b>(this, ConnectionObserver.State.CONNECTED);<span style=""></span></div><div><font color="#007fff">this即DisposableBind对象</font></div>" style="whiteSpace=wrap;html=1;fontSize=10;rounded=1;align=left;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2720" y="1839" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-20" value="<font color="#007fff">发送信号</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="2950" y="1775" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-25" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-22" target="bm2imlQ028U47hNO7TBu-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-22" value="关闭HttpServer" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="40" y="1080" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-27" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-24" target="bm2imlQ028U47hNO7TBu-26" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-24" value=".disposeNow()<br><font color="#007fff">主动关闭</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="1080" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-29" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-26" target="bm2imlQ028U47hNO7TBu-28" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-26" value="dispose();<br><font color="#007fff">关闭通道,释放资源</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="1080" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-28" value="onDispose().block(timeout);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="1160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-30" value="return FutureMono.from(channel().closeFuture());<br><font color="#007fff">closeFuture()会等待关闭通道</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="440" y="881" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-36" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-34" target="bm2imlQ028U47hNO7TBu-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-34" value="TcpServerBind#<b>dispose</b>()<br><font color="#007fff">关闭通道,释放Http资源</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="2360" y="1938.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-41" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-39" target="bm2imlQ028U47hNO7TBu-40" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-39" value="客户端连接处理" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="40" y="2079" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-52" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;" parent="1" source="bm2imlQ028U47hNO7TBu-40" target="bm2imlQ028U47hNO7TBu-51" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-40" value="<div>EpollEventLoop#<span style="background-color: initial;">run()</span></div><div><font color="#007fff">这里只分析NIO,至于为何走到这,</font></div><div><font color="#007fff">参考Netty源码流程图,4.1.43等新版本 NioEventLoop改名为了EpollEventLoop</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="2079" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-42" value="<div style="text-align: center; font-size: 10px;"><font style="font-size: 10px;"><font style="font-size: 10px;" color="#000000">reactor.netty.ConnectionObserver</font></font></div><hr style="font-size: 10px;"><font style="">此接口是TCP连接(Connection)生命周期的监听器,生命周期的5种状态:<br><br>//状态改变后回调<br><font color="#000000">void onStateChange(Connection connection, State newState);</font><br>//链接另一个ConnectionObserver<br><font color="#000000">ConnectionObserver then(ConnectionObserver other)</font><br><br>//&nbsp;interface State 内部类定义<br>// 连接被建立且可用<br><div style=""><font color="#000000">State CONNECTED = ReactorNetty.CONNECTED;</font></div><div style="">// 连接被绑定到通道操作并已准备好交互</div><div style=""><font color="#000000">State CONFIGURED = ReactorNetty.CONFIGURED;</font></div><div style=""><font color="#000000">State ACQUIRED = ReactorNetty.ACQUIRED;</font></div><div style=""><font color="#000000">State RELEASED = ReactorNetty.RELEASED;</font></div><div style=""><font color="#000000">State DISCONNECTING = ReactorNetty.DISCONNECTING;</font></div></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-960" y="801" width="440" height="239" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-43" value="<div style="text-align: center;"><font style=""><font style="font-size: 10px;" color="#000000">reactor.netty.</font><font style="background-color: initial;" color="#000000">channel.</font></font></div><div style="text-align: center;"><font color="#000000"><b>ChannelOperations</b>&lt;INBOUND extends NettyInbound, OUTBOUND extends NettyOutbound&gt;</font></div><hr style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;定义响应式的ChannelHandler</font><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><font style="font-size: 10px;" color="#000000"><br style="font-size: 10px;"></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">final Connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>connection</b>;</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">final FluxReceive&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<b>inbound</b>;</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">final ConnectionObserver&nbsp; <b>listener</b>;</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">final MonoProcessor&lt;Void&gt; <b>onTerminate</b>;</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#000000">volatile Subscription <b>outboundSubscription</b>;</font></p><div><br></div>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-1440" y="800" width="440" height="240" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-46" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;" parent="1" source="bm2imlQ028U47hNO7TBu-44" target="uSWqA2PRX45ugPRLn6LA-213" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-44" value="<div style="text-align: center;"><font style=""><font style="font-size: 10px;" color="#000000">reactor.netty.</font><font style="background-color: initial;" color="#000000">channel.</font></font><font style="background-color: initial;" color="#000000"><b>BootstrapHandlers</b></font><font style="background-color: initial;"><font style="background-color: initial;" color="#000000">.</font></font><b style="color: rgb(0, 0, 0); background-color: initial;">BootstrapPipelineHandler</b></div><div style="text-align: center;"><font color="#000000">&nbsp;extends ArrayList&lt;PipelineConfiguration&gt;&nbsp;</font><span style="color: rgb(0, 0, 0); background-color: initial;">implements ChannelHandler</span></div><hr style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;是一个List容器,存储PipelineConfiguration<br></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-1360" y="1240" width="360" height="80" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-59" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-47" target="bm2imlQ028U47hNO7TBu-58" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-47" value="doBind(localAddress);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2360" y="1601" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-49" value="<font style="font-size: 10px;">这步是Netty的源码实现,这里不细讲</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="2365" y="1661" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-50" value="<div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff"><b style="">绑定后用于监听连接的Channel的pipeline</b></font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">pipeline = {DefaultChannelPipeline@2934}</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>head</b> = {DefaultChannelPipeline$<b>HeadContext</b>@2941}</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; <b>next</b> = {DefaultChannelHandlerContext@3278} "ChannelHandlerContext(ServerBootstrap$<b>ServerBootstrapAcceptor</b>#0, [id: 0x6bc5b9d7])"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp;handler = {ServerBootstrap$ServerBootstrapAcceptor@3282}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; childGroup = {EpollEventLoopGroup@2565}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; childHandler = {BootstrapHandlers$<b>BootstrapInitializerHandler</b>@2728}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; childOptions = {Map$Entry[2]@3003}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; childAttrs = {Map$Entry[0]@3017}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; enableAutoReadTask = {ServerBootstrap$ServerBootstrapAcceptor$1@3318}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; added = true</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp;<b style="">next</b> = {DefaultChannelPipeline$<b style="">TailContext</b>@2942}</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="2800" y="1600" width="650" height="160" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-55" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-51" target="bm2imlQ028U47hNO7TBu-128" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="680" y="2108.9999999999995" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-51" value="<div>EpollEventLoop#</div><div>processReady(events, strategy)<br></div><div><font color="#007fff">注意Netty新版本没有这个方法了,新版本</font></div><font color="#007fff">在processReady</font><span style="color: rgb(0, 127, 255); background-color: initial;">()处理</span><font color="#007fff"><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="440" y="2079" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-53" value="<font color="#007fff" style="font-size: 10px;">服务端启动阶段会创建用于监听连接的Channel<br>在客户端发起连接后还会创建与客户端一对一的通信Channel<br>childHandler 就是用于通信Channel的Handler<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="40" y="2139" width="290" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-56" value="CLEANUP_GLOBAL_RESOURCE = DisposableBind::new;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1640" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-58" value="<font color="#007fff">主要是创建监听连接的Channel 和 Handler pipeline, 然后执行端口绑定操作</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="2600" y="1601" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-60" value="<div>ChannelHandler注册流程:</div><div><br></div><div>1)先新建ChannelInitializer封装成DefaultChannelHandlerContext加入pipeline末尾(tail节点前),提交Handler注册任务A到 pendingHandlerCallbackHead 链表(后面register阶段才会启动执行)</div><div>2)bind阶段,事件循环线程T启动后第一个任务执行register0(), 会扫描pendingHandlerCallbackHead并执行Handler注册任务,上面A任务会执行,A任务会再向事件循环线程池注册一个异步任务B, 用于执行用户定制的ChannelInitializer并封装ServerBootstrapAcceptor再添加到pipeline末尾, A任务执行完成会将前面默认创建的ChannelInitializer从pipeline删除掉</div><div>3)事件循环线程T的下一个循环,会扫描taskQueue读取任务B并执行,将ServerBootstrapAcceptor封装成DefaultChannelHandlerContext加入pipeline末尾</div><div>最终服务端启动阶段完成后<b>用于接收连接的Channel</b>(类NioServerSocketChannel, Acceptor)的Handler pipeline:<br><b>HeadContext &lt;---&gt;&nbsp;ServerBootstrapAcceptor &lt;---&gt; TailContext</b></div><div><span style="background-color: initial;">NioServerSocketChannel 是用于监听连接的Channel (本质是Server Socket 文件)</span><br></div><div>4)&nbsp;至于建立连接后<b>用于通信的 Channel的 Handler pipeline</b> 是在processSelectedKeys()&nbsp;<span style="background-color: initial;">接受到连接事件后,调用</span>ServerBootstrapAcceptor<span style="background-color: initial;">#channelRead() 执行子Channel Handler的注册的</span></div>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;fontSize=10;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="2600" y="1310.5" width="320" height="289.5" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-82" value="这部分流程大部分是Netty源码实现<br>由于版本不一样代码有变化,<br>重新过下Netty这部分代码" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="215" y="2013" width="210" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-87" target="bm2imlQ028U47hNO7TBu-92" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-117" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-87" target="bm2imlQ028U47hNO7TBu-108" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-87" value="<div style="font-size: 9px;"><div>for (PipelineConfiguration pipelineConfiguration : <b>pipeline</b>) {</div><div>&nbsp; pipelineConfiguration.consumer</div><div><span style="white-space: pre;">	</span>.<b>accept</b>(listener, ch);</div><div>}</div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="3320" y="2798" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-89" value="BootstrapHandlers" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="3360" y="2769" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-90" value="调 reactor-netty 代码" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="3170" y="2812" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-115" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-92" target="bm2imlQ028U47hNO7TBu-114" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-92" value="<div style=""><font size="1">ChannelOperations.addReactiveBridge(ch, opsFactory, listener);</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="3320" y="3400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-215" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-94" target="bm2imlQ028U47hNO7TBu-214" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-94" value="<div style=""><font size="1">Http1Initializer#accept()</font><br></div><div style=""><font color="#007fff" size="1">5个Handler: Http协议编解码器、访问日志记录、压缩、请求处理、监控</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3560" y="2878" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-99" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-96" target="bm2imlQ028U47hNO7TBu-98" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-217" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-96" target="bm2imlQ028U47hNO7TBu-106" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-96" value="<div style=""><font size="1">p.addLast(NettyPipeline.HttpCodec, new <b>HttpServerCodec</b>(line, header, chunk, validate, buffer));</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3800" y="2959.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-101" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-98" target="bm2imlQ028U47hNO7TBu-100" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-98" value="<div style="font-size: 9px;"><div><div style="">if (ACCESS_LOG) {</div><div>&nbsp; &nbsp; p.addLast(NettyPipeline.AccessLogHandler, <span style="white-space: pre;">	</span>new <b>AccessLogHandler</b>());</div><div>}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3800" y="3039.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-103" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-100" target="bm2imlQ028U47hNO7TBu-102" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-100" value="<div style="font-size: 9px;"><div>if (alwaysCompress) {</div><div>&nbsp; &nbsp; p.addLast(NettyPipeline.CompressionHandler,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; new <b>SimpleCompressionHandler</b>());</div><div>}</div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3800" y="3119.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-102" target="bm2imlQ028U47hNO7TBu-104" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-218" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-102" target="bm2imlQ028U47hNO7TBu-106" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-219" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-102" target="bm2imlQ028U47hNO7TBu-111" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-102" value="<div style=""><div style=""><font size="1">p.<b>addLast</b>(NettyPipeline.HttpTrafficHandler,</font></div><div style=""><font size="1">new <b>HttpTrafficHandler</b>(listener, forwarded, compressPredicate, cookieEncoder, cookieDecoder));</font></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3800" y="3198.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-104" value="<div style="font-size: 9px;"><div style=""><div>ChannelHandler handler = p.get(NettyPipeline.ChannelMetricsHandler);</div><div>if (handler != null) {</div><div>&nbsp; &nbsp; p.addAfter(NettyPipeline.HttpTrafficHandler, NettyPipeline.HttpMetricsHandler, <b>httpMetrics</b>);</div><div>}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3800" y="3277" width="200" height="81" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-106" value="<div style=""><font size="1">handlerAdded(ChannelHandlerContext ctx)</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="4080.06" y="2959.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-118" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-108" target="bm2imlQ028U47hNO7TBu-94" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-213" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-108" target="bm2imlQ028U47hNO7TBu-212" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-108" value="<div style=""><font size="1">LoggingHandlerSupportConsumer#accept()</font></div><div style=""><font color="#007fff" size="1">通过 addXxx() 注册</font></div><font color="#007fff" size="1">NettyPipeline.LoggingHandler</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3560" y="2798" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-221" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-111" target="bm2imlQ028U47hNO7TBu-220" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-111" value="<div style=""><font size="1">ctx.read()</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="4080.06" y="3198.5" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-114" value="<div style="font-size: 9px;"><div>ch.pipeline()<span style="background-color: initial;">.addLast(</span></div><div><span style="background-color: initial;">NettyPipeline.ReactiveBridge,&nbsp;</span></div><div><span style="background-color: initial;">new <b>ChannelOperationsHandler</b>(opsFactory, listener));</span></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="3560" y="3400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-116" value="<div><font color="#007fff"><b>测试案例中子Channel(用于通信的Channel) Handler pipeline</b>:</font></div><div><font color="#007fff">pipeline = {DefaultChannelPipeline@2778}</font></div><div><font color="#007fff">&nbsp;head = {DefaultChannelPipeline$HeadContext@2786}</font></div><div><font color="#007fff">&nbsp; next = {DefaultChannelHandlerContext@3132}</font></div><div><font color="#007fff">&nbsp; &nbsp;handler = {<b>LoggingHandler</b>@3136}&nbsp;</font></div><div><font color="#007fff">&nbsp; &nbsp;next = {DefaultChannelHandlerContext@2969}</font></div><div><font color="#007fff">&nbsp; &nbsp; handler = {BootstrapHandlers$<b>BootstrapInitializerHandler</b>@2800}&nbsp;</font></div><div><font color="#007fff">&nbsp; &nbsp; next = {DefaultChannelHandlerContext@3463}</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp;handler = {<b>HttpServerCodec</b>@3741}&nbsp;</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp;next = {DefaultChannelHandlerContext@3504}</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; handler = {<b>HttpTrafficHandler</b>@3503}&nbsp;</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; next = {DefaultChannelHandlerContext@3853</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;handler = {<b>ChannelOperationsHandler</b>@3852}&nbsp;</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;next = {DefaultChannelPipeline$TailContext@2787}</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="3320" y="3179.5" width="400" height="210" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-133" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-128" target="bm2imlQ028U47hNO7TBu-132" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-128" value="<div style="font-size: 9px;"><font style="font-size: 9px;">final int fd = events.fd(i);<br></font></div><div style="font-size: 9px;"><span style="background-color: initial;"><font style="font-size: 9px;">final long ev = events.events(i);<br></font></span></div><div style="font-size: 9px;"><font style="font-size: 9px;"><span style="background-color: initial;">AbstractEpollChannel ch = <b>channels</b>.get(fd);<br></span>AbstractEpollUnsafe unsafe = (AbstractEpollUnsafe) ch.unsafe();</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="680" y="2079" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-139" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-132" target="bm2imlQ028U47hNO7TBu-134" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-140" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-132" target="bm2imlQ028U47hNO7TBu-135" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-141" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-132" target="bm2imlQ028U47hNO7TBu-137" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-132" value="ev" style="rhombus;whiteSpace=wrap;html=1;fontSize=10;rounded=1;" parent="1" vertex="1">
<mxGeometry x="740" y="2231" width="80" height="72" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-143" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-134" target="bm2imlQ028U47hNO7TBu-142" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-134" value="<div style="">Native.EPOLLERR | Native.<b>EPOLLOUT</b><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="920" y="2157" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-145" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-135" target="bm2imlQ028U47hNO7TBu-144" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-135" value="<div style="">Native.EPOLLERR | Native.<b>EPOLLIN</b><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="920" y="2237" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-147" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-137" target="bm2imlQ028U47hNO7TBu-146" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-137" value="<div style="">Native.<b>EPOLLRDHUP</b><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="920" y="2317" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-142" value="<div style="">unsafe.epollOutReady();<br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1160" y="2157" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-149" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="bm2imlQ028U47hNO7TBu-144" target="bm2imlQ028U47hNO7TBu-148" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="bm2imlQ028U47hNO7TBu-236" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="bm2imlQ028U47hNO7TBu-144" target="bm2imlQ028U47hNO7TBu-237" edge="1">