Java NIO框架Netty教程(八)-Object对象传递

释放双眼,带上耳机,听听看~!

说了这么多废话,才提到对象的传输,不知道您是不是已经不耐烦了。一个系统内部的消息传递,没有对象传递是不太现实的。下面就来说说,怎么传递对象。

如果,您看过前面的介绍,如果您善于专注本质,勤于思考。您应该也会想到,我们说过,Netty的消息传递都是基于流,通过ChannelBuffer传递的,那么自然,Object也需要转换成ChannelBuffer来传递。好在Netty本身已经给我们写好了这样的转换工具。ObjectEncoder和ObjectDecoder。

工具怎么用?再一次说说所谓的本质,我们之前也说过,Netty给我们处理自己业务的空间是在灵活的可子定义的Handler上的,也就是说,如果我们自己去做这个转换工作,那么也应该在Handler里去做。而Netty,提供给我们的ObjectEncoder和Decoder也恰恰是一组Handler。于是,修改Server和Client的启动代码:


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
1// 设置一个处理客户端消息和各种消息事件的类(Handler)
2      
3
4      
5
6
7        bootstrap.setPipelineFactory(
8        new
9         ChannelPipelineFactory() {
10      
11
12      
13
14
15            
16        @Override
17      
18
19      
20
21
22            
23        public
24         ChannelPipeline getPipeline()  
25        throws
26         Exception {
27      
28
29      
30
31
32                
33        return
34         Channels.pipeline(
35      
36
37      
38
39
40                
41        new
42         ObjectDecoder(ClassResolvers.cacheDisabled(
43        this
44      
45
46      
47
48
49                        
50        .getClass().getClassLoader())),
51      
52
53      
54
55
56                
57        new
58         ObjectServerHandler());
59      
60
61      
62
63
64            
65        }
66      
67
68      
69
70
71        });
72

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
1// 设置一个处理服务端消息和各种消息事件的类(Handler)
2      
3
4      
5
6
7        bootstrap.setPipelineFactory(
8        new
9         ChannelPipelineFactory() {
10      
11
12      
13
14
15            
16        @Override
17      
18
19      
20
21
22            
23        public
24         ChannelPipeline getPipeline()  
25        throws
26         Exception {
27      
28
29      
30
31
32                
33        return
34         Channels.pipeline(
35        new
36         ObjectEncoder(),
37      
38
39      
40
41
42                        
43        new
44         ObjectClientHandler());
45      
46
47      
48
49
50            
51        }
52      
53
54      
55
56
57        });
58

要传递对象,自然要有一个被传递模型,一个简单的Pojo,当然,实现序列化接口是必须的。


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
1/**
2      
3
4      
5
6
7         
8        * @author lihzh
9      
10
11      
12
13
14         
15        * @alia OneCoder
16      
17
18      
19
20
21         
22        * @blog  http://www.coderli.com
23      
24
25      
26
27
28         
29        */
30      
31
32      
33
34
35        public
36         class
37         Command  
38        implements
39         Serializable {
40      
41
42      
43
44
45          
46      
47
48      
49
50
51            
52        private
53         static
54         final
55         long
56         serialVersionUID = 7590999461767050471L;
57      
58
59      
60
61
62          
63      
64
65      
66
67
68            
69        private
70         String actionName;
71      
72
73      
74
75
76          
77      
78
79      
80
81
82            
83        public
84         String getActionName() {
85      
86
87      
88
89
90                
91        return
92         actionName;
93      
94
95      
96
97
98            
99        }
100      
101
102      
103
104
105          
106      
107
108      
109
110
111            
112        public
113         void
114         setActionName(String actionName) {
115      
116
117      
118
119
120                
121        this
122        .actionName = actionName;
123      
124
125      
126
127
128            
129        }
130      
131
132      
133
134
135        }
136

服务端和客户端里,我们自定义的Handler实现如下:


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
1/**
2      
3
4      
5
6
7         
8        * 对象传递服务端代码
9      
10
11      
12
13
14         
15        *  
16      
17
18      
19
20
21         
22        * @author lihzh
23      
24
25      
26
27
28         
29        * @alia OneCoder
30      
31
32      
33
34
35         
36        * @blog  http://www.coderli.com
37      
38
39      
40
41
42         
43        */
44      
45
46      
47
48
49        public
50         class
51         ObjectServerHandler  
52        extends
53         SimpleChannelHandler {
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        @Override
88      
89
90      
91
92
93            
94        public
95         void
96         messageReceived(ChannelHandlerContext ctx, MessageEvent e)
97      
98
99      
100
101
102                    
103        throws
104         Exception {
105      
106
107      
108
109
110                
111        Command command = (Command) e.getMessage();
112      
113
114      
115
116
117                
118        // 打印看看是不是我们刚才传过来的那个
119      
120
121      
122
123
124                
125        System.out.println(command.getActionName());
126      
127
128      
129
130
131            
132        }
133      
134
135      
136
137
138        }
139

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
1/**
2      
3
4      
5
6
7         
8        * 对象传递,客户端代码
9      
10
11      
12
13
14         
15        *  
16      
17
18      
19
20
21         
22        * @author lihzh
23      
24
25      
26
27
28         
29        * @alia OneCoder
30      
31
32      
33
34
35         
36        * @blog  http://www.coderli.com
37      
38
39      
40
41
42         
43        */
44      
45
46      
47
48
49        public
50         class
51         ObjectClientHandler  
52        extends
53         SimpleChannelHandler {
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        * @author lihzh
88      
89
90      
91
92
93             
94        * @alia OneCoder
95      
96
97      
98
99
100             
101        */
102      
103
104      
105
106
107            
108        @Override
109      
110
111      
112
113
114            
115        public
116         void
117         channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
118      
119
120      
121
122
123                
124        // 向服务端发送Object信息
125      
126
127      
128
129
130                
131        sendObject(e.getChannel());
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        * 发送Object
159      
160
161      
162
163
164             
165        *  
166      
167
168      
169
170
171             
172        * @param channel
173      
174
175      
176
177
178             
179        * @author lihzh
180      
181
182      
183
184
185             
186        * @alia OneCoder
187      
188
189      
190
191
192             
193        */
194      
195
196      
197
198
199            
200        private
201         void
202         sendObject(Channel channel) {
203      
204
205      
206
207
208                
209        Command command =  
210        new
211         Command();
212      
213
214      
215
216
217                
218        command.setActionName(
219        "Hello action."
220        );
221      
222
223      
224
225
226                
227        channel.write(command);
228      
229
230      
231
232
233            
234        }
235      
236
237      
238
239
240          
241      
242
243      
244
245
246        }
247

启动后,服务端正常打印结果:Hello action.

简单梳理一下思路:

  1. 通过Netty传递,都需要基于流,以ChannelBuffer的形式传递。所以,Object -> ChannelBuffer.
  2. Netty提供了转换工具,需要我们配置到Handler。
  3. 样例从客户端 -> 服务端,单向发消息,所以在客户端配置了编码,服务端解码。如果双向收发,则需要全部配置Encoder和Decoder。

这里需要注意,注册到Server的Handler是有顺序的,如果你颠倒一下注册顺序:


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
1bootstrap.setPipelineFactory(
2         new
3          ChannelPipelineFactory() {
4        
5
6        
7
8
9             
10         @Override
11        
12
13        
14
15
16             
17         public
18          ChannelPipeline getPipeline()  
19         throws
20          Exception {
21        
22
23        
24
25
26                 
27         return
28          Channels.pipeline(
29         new
30          ObjectServerHandler(),
31        
32
33        
34
35
36                         
37         new
38          ObjectDecoder(ClassResolvers.cacheDisabled(
39         this
40        
41
42        
43
44
45                                 
46         .getClass().getClassLoader()))
47        
48
49        
50
51
52                         
53         );
54        
55
56        
57
58
59             
60         }
61        
62
63        
64
65
66         });
67

结果就是,会先进入我们自己的业务,再进行解码。这自然是不行的,会强转失败。至此,你应该会用Netty传递对象了吧。

如非特别注明,本站内容均为OneCoder原创,转载请务必注明作者和原始出处。

本文地址:链接地址

给TA打赏
共{{data.count}}人
人已打赏
安全技术

Bootstrap 4 Flex(弹性)布局

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索