View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.example.discard;
17  
18  import org.jboss.netty.buffer.ChannelBuffer;
19  import org.jboss.netty.buffer.ChannelBuffers;
20  import org.jboss.netty.channel.Channel;
21  import org.jboss.netty.channel.ChannelEvent;
22  import org.jboss.netty.channel.ChannelHandlerContext;
23  import org.jboss.netty.channel.ChannelState;
24  import org.jboss.netty.channel.ChannelStateEvent;
25  import org.jboss.netty.channel.ExceptionEvent;
26  import org.jboss.netty.channel.MessageEvent;
27  import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
28  import org.jboss.netty.channel.WriteCompletionEvent;
29  
30  /**
31   * Handles a client-side channel.
32   */
33  public class DiscardClientHandler extends SimpleChannelUpstreamHandler {
34  
35      private long transferredBytes;
36      private final byte[] content;
37  
38      public DiscardClientHandler() {
39          content = new byte[DiscardClient.SIZE];
40      }
41  
42      public long getTransferredBytes() {
43          return transferredBytes;
44      }
45  
46      @Override
47      public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
48          if (e instanceof ChannelStateEvent) {
49              if (((ChannelStateEvent) e).getState() != ChannelState.INTEREST_OPS) {
50                  System.err.println(e);
51              }
52          }
53  
54          // Let SimpleChannelHandler call actual event handler methods below.
55          super.handleUpstream(ctx, e);
56      }
57  
58      @Override
59      public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
60          // Send the initial messages.
61          generateTraffic(e);
62      }
63  
64      @Override
65      public void channelInterestChanged(ChannelHandlerContext ctx, ChannelStateEvent e) {
66          // Keep sending messages whenever the current socket buffer has room.
67          generateTraffic(e);
68      }
69  
70      @Override
71      public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
72          // Server is supposed to send nothing.  Therefore, do nothing.
73      }
74  
75      @Override
76      public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e) {
77          transferredBytes += e.getWrittenAmount();
78      }
79  
80      @Override
81      public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
82          // Close the connection when an exception is raised.
83          e.getCause().printStackTrace();
84          e.getChannel().close();
85      }
86  
87      private void generateTraffic(ChannelStateEvent e) {
88          // Keep generating traffic until the channel is unwritable.
89          // A channel becomes unwritable when its internal buffer is full.
90          // If you keep writing messages ignoring this property,
91          // you will end up with an OutOfMemoryError.
92          Channel channel = e.getChannel();
93          while (channel.isWritable()) {
94              ChannelBuffer m = nextMessage();
95              if (m == null) {
96                  break;
97              }
98              channel.write(m);
99          }
100     }
101 
102     private ChannelBuffer nextMessage() {
103         return ChannelBuffers.wrappedBuffer(content);
104     }
105 }