Made the echo example easier to understand by splitting EchoHandler into EchoClientHandler and EchoServerHandler

This commit is contained in:
Trustin Lee 2009-09-04 03:01:58 +00:00
parent 5345c7f509
commit f79fd584d1
7 changed files with 97 additions and 22 deletions

View File

@ -60,7 +60,7 @@ public class EchoClient {
Executors.newCachedThreadPool())); Executors.newCachedThreadPool()));
// Set up the default event pipeline. // Set up the default event pipeline.
EchoHandler handler = new EchoHandler(firstMessageSize); EchoClientHandler handler = new EchoClientHandler(firstMessageSize);
bootstrap.getPipeline().addLast("handler", handler); bootstrap.getPipeline().addLast("handler", handler);
// Start the connection attempt. // Start the connection attempt.

View File

@ -29,8 +29,9 @@ import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler; import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
/** /**
* Handles both client-side and server-side handler depending on which * Handler implementation for the echo client. It initiates the ping-pong
* constructor was called. * traffic between the echo client and server by sending the first message to
* the server.
* *
* @author The Netty Project (netty-dev@lists.jboss.org) * @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com) * @author Trustin Lee (tlee@redhat.com)
@ -38,25 +39,18 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
* @version $Rev$, $Date$ * @version $Rev$, $Date$
*/ */
@ChannelPipelineCoverage("all") @ChannelPipelineCoverage("all")
public class EchoHandler extends SimpleChannelUpstreamHandler { public class EchoClientHandler extends SimpleChannelUpstreamHandler {
private static final Logger logger = Logger.getLogger( private static final Logger logger = Logger.getLogger(
EchoHandler.class.getName()); EchoClientHandler.class.getName());
private final ChannelBuffer firstMessage; private final ChannelBuffer firstMessage;
private final AtomicLong transferredBytes = new AtomicLong(); private final AtomicLong transferredBytes = new AtomicLong();
/**
* Creates a server-side handler.
*/
public EchoHandler() {
firstMessage = ChannelBuffers.EMPTY_BUFFER;
}
/** /**
* Creates a client-side handler. * Creates a client-side handler.
*/ */
public EchoHandler(int firstMessageSize) { public EchoClientHandler(int firstMessageSize) {
if (firstMessageSize <= 0) { if (firstMessageSize <= 0) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"firstMessageSize: " + firstMessageSize); "firstMessageSize: " + firstMessageSize);

View File

@ -40,7 +40,7 @@ public class EchoServer {
Executors.newCachedThreadPool())); Executors.newCachedThreadPool()));
// Set up the default event pipeline. // Set up the default event pipeline.
EchoHandler handler = new EchoHandler(); EchoServerHandler handler = new EchoServerHandler();
bootstrap.getPipeline().addLast("handler", handler); bootstrap.getPipeline().addLast("handler", handler);
// Bind and start to accept incoming connections. // Bind and start to accept incoming connections.

View File

@ -0,0 +1,67 @@
/*
* Copyright 2009 Red Hat, Inc.
*
* Red Hat licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.jboss.netty.example.echo;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
/**
* Handler implementation for the echo server.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev: 1685 $, $Date: 2009-08-28 16:15:49 +0900 (Fri, 28 Aug 2009) $
*/
@ChannelPipelineCoverage("all")
public class EchoServerHandler extends SimpleChannelUpstreamHandler {
private static final Logger logger = Logger.getLogger(
EchoServerHandler.class.getName());
private final AtomicLong transferredBytes = new AtomicLong();
public long getTransferredBytes() {
return transferredBytes.get();
}
@Override
public void messageReceived(
ChannelHandlerContext ctx, MessageEvent e) {
// Send back the received message to the remote peer.
transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
e.getChannel().write(e.getMessage());
}
@Override
public void exceptionCaught(
ChannelHandlerContext ctx, ExceptionEvent e) {
// Close the connection when an exception is raised.
logger.log(
Level.WARNING,
"Unexpected exception from downstream.",
e.getCause());
e.getChannel().close();
}
}

View File

@ -15,6 +15,8 @@
*/ */
package org.jboss.netty.example.echo; package org.jboss.netty.example.echo;
import org.jboss.netty.channel.ChannelHandler;
/** /**
* Measures and prints the current throughput every 3 seconds. * Measures and prints the current throughput every 3 seconds.
* *
@ -25,15 +27,19 @@ package org.jboss.netty.example.echo;
*/ */
public class ThroughputMonitor extends Thread { public class ThroughputMonitor extends Thread {
private final EchoHandler handler; private final ChannelHandler handler;
public ThroughputMonitor(EchoHandler handler) { public ThroughputMonitor(EchoClientHandler handler) {
this.handler = handler;
}
public ThroughputMonitor(EchoServerHandler handler) {
this.handler = handler; this.handler = handler;
} }
@Override @Override
public void run() { public void run() {
long oldCounter = handler.getTransferredBytes(); long oldCounter = getTransferredBytes();
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
for (;;) { for (;;) {
try { try {
@ -43,7 +49,7 @@ public class ThroughputMonitor extends Thread {
} }
long endTime = System.currentTimeMillis(); long endTime = System.currentTimeMillis();
long newCounter = handler.getTransferredBytes(); long newCounter = getTransferredBytes();
System.err.format( System.err.format(
"%4.3f MiB/s%n", "%4.3f MiB/s%n",
(newCounter - oldCounter) * 1000.0 / (endTime - startTime) / (newCounter - oldCounter) * 1000.0 / (endTime - startTime) /
@ -52,4 +58,12 @@ public class ThroughputMonitor extends Thread {
startTime = endTime; startTime = endTime;
} }
} }
private long getTransferredBytes() {
if (handler instanceof EchoClientHandler) {
return ((EchoClientHandler) handler).getTransferredBytes();
} else {
return ((EchoServerHandler) handler).getTransferredBytes();
}
}
} }

View File

@ -20,7 +20,7 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.local.DefaultLocalServerChannelFactory; import org.jboss.netty.channel.local.DefaultLocalServerChannelFactory;
import org.jboss.netty.channel.local.LocalAddress; import org.jboss.netty.channel.local.LocalAddress;
import org.jboss.netty.example.echo.EchoHandler; import org.jboss.netty.example.echo.EchoServerHandler;
/** /**
* Deploy this in JBossAS 5 or other IoC container by adding the following bean. * Deploy this in JBossAS 5 or other IoC container by adding the following bean.
@ -41,7 +41,7 @@ public class LocalEchoServerRegistration {
public void start() { public void start() {
ServerBootstrap serverBootstrap = new ServerBootstrap(factory); ServerBootstrap serverBootstrap = new ServerBootstrap(factory);
EchoHandler handler = new EchoHandler(); EchoServerHandler handler = new EchoServerHandler();
serverBootstrap.getPipeline().addLast("handler", handler); serverBootstrap.getPipeline().addLast("handler", handler);
// Note that "myLocalServer" is the endpoint which was specified in web.xml. // Note that "myLocalServer" is the endpoint which was specified in web.xml.

View File

@ -24,7 +24,7 @@ import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.local.DefaultLocalClientChannelFactory; import org.jboss.netty.channel.local.DefaultLocalClientChannelFactory;
import org.jboss.netty.channel.local.DefaultLocalServerChannelFactory; import org.jboss.netty.channel.local.DefaultLocalServerChannelFactory;
import org.jboss.netty.channel.local.LocalAddress; import org.jboss.netty.channel.local.LocalAddress;
import org.jboss.netty.example.echo.EchoHandler; import org.jboss.netty.example.echo.EchoServerHandler;
import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder; import org.jboss.netty.handler.codec.string.StringEncoder;
import org.jboss.netty.handler.logging.LoggingHandler; import org.jboss.netty.handler.logging.LoggingHandler;
@ -45,7 +45,7 @@ public class LocalExample {
new DefaultLocalServerChannelFactory()); new DefaultLocalServerChannelFactory());
// Set up the default server-side event pipeline. // Set up the default server-side event pipeline.
EchoHandler handler = new EchoHandler(); EchoServerHandler handler = new EchoServerHandler();
sb.getPipeline().addLast("handler", handler); sb.getPipeline().addLast("handler", handler);
// Start up the server. // Start up the server.