2929import com .qq .tars .rpc .protocol .tars .support .AnalystManager ;
3030import com .qq .tars .rpc .protocol .tup .UniAttribute ;
3131import io .netty .buffer .ByteBuf ;
32- import io .netty .buffer .Unpooled ;
32+ import io .netty .buffer .ByteBufAllocator ;
33+ import io .netty .buffer .CompositeByteBuf ;
3334import io .netty .channel .ChannelHandlerContext ;
3435import io .netty .handler .codec .MessageToByteEncoder ;
36+ import io .netty .util .ReferenceCountUtil ;
3537import org .slf4j .Logger ;
3638import org .slf4j .LoggerFactory ;
3739
@@ -49,60 +51,85 @@ public TarsEncoder(Charset charset) {
4951
5052 @ Override
5153 protected void encode (ChannelHandlerContext channelHandlerContext , Object o , ByteBuf out ) throws Exception {
52- if (o instanceof Request ) {
53- try {
54- final ByteBuf ioBuffer = encodeRequest ((TarsServantRequest ) o );
54+ ByteBuf ioBuffer = null ;
55+ try {
56+ if (o instanceof Request ) {
57+ try {
58+ ioBuffer = encodeRequest (channelHandlerContext .alloc (), (TarsServantRequest ) o );
59+ if (logger .isDebugEnabled ())
60+ logger .debug ("[tars] write data size is " + ioBuffer .duplicate ().getInt (0 ));
61+
62+ int length = ioBuffer .getInt (0 );
63+ if (length > ioBuffer .readableBytes ()) {
64+ throw new IndexOutOfBoundsException ();
65+ }
66+ out .ensureWritable (ioBuffer .readableBytes ());
67+ out .writeBytes (ioBuffer );
68+ } catch (Exception e ) {
69+ logger .warn (e .getMessage (), e );
70+ }
71+ } else if (o instanceof Response ) {
72+ ioBuffer = encodeResponse (channelHandlerContext .alloc (), (Response ) o );
5573 if (logger .isDebugEnabled ())
5674 logger .debug ("[tars] write data size is " + ioBuffer .duplicate ().getInt (0 ));
5775 int length = ioBuffer .getInt (0 );
5876 if (length > ioBuffer .readableBytes ()) {
5977 throw new IndexOutOfBoundsException ();
6078 }
6179 out .writeBytes (ioBuffer );
62- } catch ( Exception e ) {
63- e . printStackTrace ( );
80+ } else {
81+ throw new ProtocolException ( "[tars] cannot support type" );
6482 }
65- } else if (o instanceof Response ) {
66- final ByteBuf ioBuffer = encodeResponse ((Response ) o );
67- if (logger .isDebugEnabled ())
68- logger .debug ("[tars] write data size is " + ioBuffer .duplicate ().getInt (0 ));
69- int length = ioBuffer .getInt (0 );
70- if (length > ioBuffer .readableBytes ()) {
71- throw new IndexOutOfBoundsException ();
83+ } finally {
84+ if (ioBuffer != null ) {
85+ ReferenceCountUtil .release (ioBuffer );
7286 }
73- out .writeBytes (ioBuffer );
74- } else {
75- throw new ProtocolException ("[tars] cannot support type" );
7687 }
7788 }
7889
7990
80- public ByteBuf encodeRequest (Request req ) throws ProtocolException {
91+ public ByteBuf encodeRequest (ByteBufAllocator allocator , Request req ) throws ProtocolException {
8192 final TarsServantRequest request = (TarsServantRequest ) req ;
82- request .setCharsetName (this .charset .name ());
83- TarsOutputStream os = new TarsOutputStream ();
84- os .setServerEncoding (this .charset );
85- os .getByteBuffer ().writeInt (0 );
86- os .write (request .getVersion (), 1 );
87- os .write (request .getPacketType (), 2 );
88- os .write (request .getMessageType (), 3 );
89- os .write (request .getRequestId (), 4 );
90- os .write (request .getServantName (), 5 );
91- os .write (request .getFunctionName (), 6 );
92- os .write (encodeRequestParams (request ), 7 );//
93- os .write (request .getTimeout (), 8 );
94- os .write (request .getContext (), 9 );
95- os .write (request .getStatus (), 10 );
96- int length = os .getByteBuffer ().readableBytes ();
97- os .getByteBuffer ().setInt (0 , length );
98- if (length > TarsHelper .PACKAGE_MAX_LENGTH || length <= 0 ) {
99- throw new ProtocolException ("the length header of the package must be between 0~10M bytes. data length:" + Integer .toHexString (length ));
93+ CompositeByteBuf compositeByteBuf = allocator .compositeBuffer ();
94+ ByteBuf headBuffer = allocator .buffer ();
95+ ByteBuf bodyBuffer = allocator .buffer ();
96+ ByteBuf endBuffer = allocator .buffer ();
97+ int length = 0 ;
98+ try {
99+ request .setCharsetName (this .charset .name ());
100+ TarsOutputStream os = new TarsOutputStream (headBuffer );
101+ os .setServerEncoding (this .charset );
102+ os .getByteBuffer ().writeInt (0 );
103+ os .write (request .getVersion (), 1 );
104+ os .write (request .getPacketType (), 2 );
105+ os .write (request .getMessageType (), 3 );
106+ os .write (request .getRequestId (), 4 );
107+ os .write (request .getServantName (), 5 );
108+ os .write (request .getFunctionName (), 6 );
109+ encodeRequestParams (bodyBuffer , request );
110+ os .writBodyeHead (bodyBuffer , 7 );//
111+ TarsOutputStream endStream = new TarsOutputStream (endBuffer );
112+ endStream .write (request .getTimeout (), 8 );
113+ endStream .write (request .getContext (), 9 );
114+ endStream .write (request .getStatus (), 10 );
115+ length = os .getByteBuffer ().readableBytes () + bodyBuffer .readableBytes () + endStream .getByteBuffer ().readableBytes ();
116+ os .getByteBuffer ().setInt (0 , length );
117+ compositeByteBuf .addComponents (true , headBuffer , bodyBuffer , endBuffer );
118+
119+ } catch (Exception e ) {
120+ //when encode exception
121+ ReferenceCountUtil .release (headBuffer );
122+ ReferenceCountUtil .release (bodyBuffer );
123+ ReferenceCountUtil .release (endBuffer );
124+ if (length > TarsHelper .PACKAGE_MAX_LENGTH || length <= 0 ) {
125+ throw new ProtocolException ("the length header of the package must be between 0~10M bytes. data length:" + Integer .toHexString (length ));
126+ }
100127 }
101- return os . getByteBuffer () ;
128+ return compositeByteBuf ;
102129 }
103130
104- protected ByteBuf encodeRequestParams (TarsServantRequest request ) throws ProtocolException {
105- TarsOutputStream os = new TarsOutputStream ();
131+ protected void encodeRequestParams (ByteBuf byteBuf , TarsServantRequest request ) throws ProtocolException {
132+ TarsOutputStream os = new TarsOutputStream (byteBuf );
106133 os .setServerEncoding (this .charset );
107134 TarsMethodInfo methodInfo = request .getMethodInfo ();
108135 List <TarsMethodParameterInfo > parameterInfoList = methodInfo .getParametersList ();
@@ -127,79 +154,92 @@ protected ByteBuf encodeRequestParams(TarsServantRequest request) throws Protoco
127154 }
128155
129156 }
130- return os .getByteBuffer ();
131157 }
132158
133159
134- public ByteBuf encodeResponse (Response resp ) throws ProtocolException {
160+ public ByteBuf encodeResponse (ByteBufAllocator allocator , Response resp ) throws ProtocolException {
135161 TarsServantResponse response = (TarsServantResponse ) resp ;
136162 if (response .getPacketType () == TarsHelper .ONEWAY ) {
137163 return null ;
138164 }
139- TarsOutputStream jos = new TarsOutputStream ();
140- jos .setServerEncoding (charset );
165+ CompositeByteBuf compositeByteBuf = allocator .compositeBuffer ();
166+ ByteBuf headBuffer = allocator .buffer ();
167+ ByteBuf bodyBuffer = allocator .buffer ();
168+ ByteBuf endBuffer = allocator .buffer ();
141169 try {
142- jos .getByteBuffer ().writeInt (0 );
143- jos .write (response .getVersion (), 1 );
144- jos .write (response .getPacketType (), 2 );
170+ TarsOutputStream jos = new TarsOutputStream (headBuffer );
171+ jos .setServerEncoding (charset );
172+ try {
173+ jos .getByteBuffer ().writeInt (0 );
174+ jos .write (response .getVersion (), 1 );
175+ jos .write (response .getPacketType (), 2 );
145176
146- if (response .getVersion () == TarsHelper .VERSION ) {
147- jos .write (response .getRequestId (), 3 );
148- jos .write (response .getMessageType (), 4 );
149- jos .write (response .getRet (), 5 );
150- jos .write (encodeResult (response ), 6 );
151- if (response .getStatus () != null ) {
152- jos .write (response .getStatus (), 7 );
153- }
154- if (response .getRet () != TarsHelper .SERVERSUCCESS ) {
155- jos .write (StringUtils .isEmpty (response .getRemark ()) ? "" : response .getRemark (), 8 );
156- }
157- } else if (TarsHelper .VERSION2 == response .getVersion () || TarsHelper .VERSION3 == response .getVersion ()) {
158- jos .write (response .getMessageType (), 3 );
159- jos .write (response .getRequestId (), 4 );
160- String servantName = response .getRequest ().getServantName ();
161- jos .write (servantName , 5 );
162- jos .write (response .getRequest ().getFunctionName (), 6 );
163- jos .write (encodeWupResult (response ), 7 );
164- jos .write (response .getTimeout (), 8 );
165- if (response .getContext () != null ) {
166- jos .write (response .getContext (), 9 );
167- }
168- if (response .getStatus () != null ) {
169- jos .write (response .getStatus (), 10 );
170- }
171- } else if (response .getVersion () == TarsHelper .VERSIONJSON ) {
172- jos .write (response .getRequestId (), 3 );
173- jos .write (response .getMessageType (), 4 );
174- jos .write (response .getRet (), 5 );
175- jos .write (encodeJsonResult (response ), 6 );
176- if (response .getStatus () != null ) {
177- jos .write (response .getStatus (), 7 );
177+ if (response .getVersion () == TarsHelper .VERSION ) {
178+ jos .write (response .getRequestId (), 3 );
179+ jos .write (response .getMessageType (), 4 );
180+ jos .write (response .getRet (), 5 );
181+ encodeResult (bodyBuffer , response );
182+ jos .writBodyeHead (bodyBuffer , 6 );
183+ TarsOutputStream tarsOutputStream = new TarsOutputStream (endBuffer );
184+ if (response .getStatus () != null ) {
185+ tarsOutputStream .write (response .getStatus (), 7 );
186+ }
187+ if (response .getRet () != TarsHelper .SERVERSUCCESS ) {
188+ tarsOutputStream .write (StringUtils .isEmpty (response .getRemark ()) ? "" : response .getRemark (), 8 );
189+ }
190+ } else if (TarsHelper .VERSION2 == response .getVersion () || TarsHelper .VERSION3 == response .getVersion ()) {
191+ jos .write (response .getMessageType (), 3 );
192+ jos .write (response .getRequestId (), 4 );
193+ String servantName = response .getRequest ().getServantName ();
194+ jos .write (servantName , 5 );
195+ jos .write (response .getRequest ().getFunctionName (), 6 );
196+ jos .write (encodeWupResult (response ), 7 );
197+ jos .write (response .getTimeout (), 8 );
198+ if (response .getContext () != null ) {
199+ jos .write (response .getContext (), 9 );
200+ }
201+ if (response .getStatus () != null ) {
202+ jos .write (response .getStatus (), 10 );
203+ }
204+ } else if (response .getVersion () == TarsHelper .VERSIONJSON ) {
205+ jos .write (response .getRequestId (), 3 );
206+ jos .write (response .getMessageType (), 4 );
207+ jos .write (response .getRet (), 5 );
208+ jos .write (encodeJsonResult (response ), 6 );
209+ if (response .getStatus () != null ) {
210+ jos .write (response .getStatus (), 7 );
211+ }
212+ if (response .getRet () != TarsHelper .SERVERSUCCESS ) {
213+ jos .write (StringUtils .isEmpty (response .getRemark ()) ? "" : response .getRemark (), 8 );
214+ }
215+ } else {
216+ response .setRet (TarsHelper .SERVERENCODEERR );
217+ System .err .println ("un supported protocol, ver=" + response .getVersion ());
178218 }
179- if (response .getRet () != TarsHelper .SERVERSUCCESS ) {
180- jos .write (StringUtils .isEmpty (response .getRemark ()) ? "" : response .getRemark (), 8 );
219+ } catch (Exception ex ) {
220+ if (response .getRet () == TarsHelper .SERVERSUCCESS ) {
221+ response .setRet (TarsHelper .SERVERENCODEERR );
181222 }
182- } else {
183- response .setRet (TarsHelper .SERVERENCODEERR );
184- System .err .println ("un supported protocol, ver=" + response .getVersion ());
185- }
186- } catch (Exception ex ) {
187- if (response .getRet () == TarsHelper .SERVERSUCCESS ) {
188- response .setRet (TarsHelper .SERVERENCODEERR );
189223 }
224+ final int dataLength = headBuffer .readableBytes () + bodyBuffer .readableBytes () + endBuffer .readableBytes ();
225+ headBuffer .setInt (0 , dataLength );//write real data length
226+ compositeByteBuf .addComponents (true , headBuffer , bodyBuffer , endBuffer );
227+ } catch (Exception e ) {
228+ //when encode exception
229+ ReferenceCountUtil .release (headBuffer );
230+ ReferenceCountUtil .release (bodyBuffer );
231+ ReferenceCountUtil .release (endBuffer );
232+ System .err .println ("un supported protocol, ver=" + response .getVersion ());
190233 }
191- final ByteBuf buffer = jos .getByteBuffer ();
192- final int dataLength = buffer .readableBytes ();
193- jos .getByteBuffer ().setInt (0 , dataLength );//write real data length
194- return buffer ;
234+ return compositeByteBuf ;
195235 }
196236
197- protected ByteBuf encodeResult (TarsServantResponse response ) {
237+ protected void encodeResult (ByteBuf bytebuf , TarsServantResponse response ) {
198238 TarsServantRequest request = (TarsServantRequest ) response .getRequest ();
199239 if (TarsHelper .isPing (request .getFunctionName ())) {
200- return Unpooled . buffer () ;
240+ return ;
201241 }
202- TarsOutputStream ajos = new TarsOutputStream ();
242+ TarsOutputStream ajos = new TarsOutputStream (bytebuf );
203243 ajos .setServerEncoding (charset );
204244 int ret = response .getRet ();
205245 Map <String , TarsMethodInfo > methodInfoMap = AnalystManager .getInstance ().getMethodMapByName (request .getServantName ());
@@ -229,7 +269,6 @@ protected ByteBuf encodeResult(TarsServantResponse response) {
229269 }
230270 }
231271 }
232- return ajos .getByteBuffer ();
233272 }
234273
235274 protected byte [] encodeWupResult (TarsServantResponse response ) {
@@ -311,6 +350,7 @@ protected byte[] encodeJsonResult(TarsServantResponse response) {
311350 String result = object .toString ();
312351 return result .getBytes (charset );
313352 }
353+
314354}
315355
316356
0 commit comments