说了这么多废话,才提到对象的传输,不知道您是不是已经不耐烦了。一个系统内部的消息传递,没有对象传递是不太现实的。下面就来说说,怎么传递对象。
如果,您看过前面的介绍,如果您善于专注本质,勤于思考。您应该也会想到,我们说过,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.
简单梳理一下思路:
- 通过Netty传递,都需要基于流,以ChannelBuffer的形式传递。所以,Object -> ChannelBuffer.
- Netty提供了转换工具,需要我们配置到Handler。
- 样例从客户端 -> 服务端,单向发消息,所以在客户端配置了编码,服务端解码。如果双向收发,则需要全部配置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原创,转载请务必注明作者和原始出处。
本文地址:链接地址