Add an example client for codec-redis
Motivation: - Add an example Redis client using codec-redis. Modifications: - Add an example Redis client that reads input from STDIN and writes output to STDOUT. Result: - Added an example Redis client using codec-redis.
This commit is contained in:
parent
5eb0127c2a
commit
946d033379
@ -65,6 +65,11 @@
|
||||
<artifactId>netty-codec-memcache</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>netty-codec-redis</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>netty-codec-socks</artifactId>
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2016 The Netty Project
|
||||
*
|
||||
* The Netty Project 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 io.netty.example.redis;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.redis.RedisArrayAggregator;
|
||||
import io.netty.handler.codec.redis.RedisBulkStringAggregator;
|
||||
import io.netty.handler.codec.redis.RedisDecoder;
|
||||
import io.netty.handler.codec.redis.RedisEncoder;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* Simple Redis client that demonstrates Redis commands against a Redis server.
|
||||
*/
|
||||
public class RedisClient {
|
||||
private static final String HOST = System.getProperty("host", "127.0.0.1");
|
||||
private static final int PORT = Integer.parseInt(System.getProperty("port", "6379"));
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
EventLoopGroup group = new NioEventLoopGroup();
|
||||
try {
|
||||
Bootstrap b = new Bootstrap();
|
||||
b.group(group)
|
||||
.channel(NioSocketChannel.class)
|
||||
.handler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
ChannelPipeline p = ch.pipeline();
|
||||
p.addLast(new RedisDecoder());
|
||||
p.addLast(new RedisBulkStringAggregator());
|
||||
p.addLast(new RedisArrayAggregator());
|
||||
p.addLast(new RedisEncoder());
|
||||
p.addLast(new RedisClientHandler());
|
||||
}
|
||||
});
|
||||
|
||||
// Start the connection attempt.
|
||||
Channel ch = b.connect(HOST, PORT).sync().channel();
|
||||
|
||||
// Read commands from the stdin.
|
||||
System.out.println("Enter Redis commands (quit to end)");
|
||||
ChannelFuture lastWriteFuture = null;
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
|
||||
for (;;) {
|
||||
final String input = in.readLine();
|
||||
final String line = input != null ? input.trim() : null;
|
||||
if (line == null || "quit".equalsIgnoreCase(line)) { // EOF or "quit"
|
||||
ch.close().sync();
|
||||
break;
|
||||
} else if (line.isEmpty()) { // skip `enter` or `enter` with spaces.
|
||||
continue;
|
||||
}
|
||||
// Sends the received line to the server.
|
||||
lastWriteFuture = ch.writeAndFlush(line);
|
||||
lastWriteFuture.addListener(new GenericFutureListener<ChannelFuture>() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
System.err.print("write failed: ");
|
||||
future.cause().printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Wait until all messages are flushed before closing the channel.
|
||||
if (lastWriteFuture != null) {
|
||||
lastWriteFuture.sync();
|
||||
}
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2016 The Netty Project
|
||||
*
|
||||
* The Netty Project 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 io.netty.example.redis;
|
||||
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.handler.codec.CodecException;
|
||||
import io.netty.handler.codec.redis.ArrayRedisMessage;
|
||||
import io.netty.handler.codec.redis.ErrorRedisMessage;
|
||||
import io.netty.handler.codec.redis.FullBulkStringRedisMessage;
|
||||
import io.netty.handler.codec.redis.IntegerRedisMessage;
|
||||
import io.netty.handler.codec.redis.RedisMessage;
|
||||
import io.netty.handler.codec.redis.SimpleStringRedisMessage;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An example Redis client handler. This handler read input from STDIN and write output to STDOUT.
|
||||
*/
|
||||
public class RedisClientHandler extends ChannelDuplexHandler {
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
|
||||
String[] commands = ((String) msg).split("\\s+");
|
||||
List<RedisMessage> children = new ArrayList<RedisMessage>(commands.length);
|
||||
for (String cmdString : commands) {
|
||||
children.add(new FullBulkStringRedisMessage(ByteBufUtil.writeUtf8(ctx.alloc(), cmdString)));
|
||||
}
|
||||
RedisMessage request = new ArrayRedisMessage(children);
|
||||
ctx.write(request, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
RedisMessage redisMessage = (RedisMessage) msg;
|
||||
printAggregatedRedisResponse(redisMessage);
|
||||
ReferenceCountUtil.release(redisMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
System.err.print("exceptionCaught: ");
|
||||
cause.printStackTrace(System.err);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
private static void printAggregatedRedisResponse(RedisMessage msg) {
|
||||
if (msg instanceof SimpleStringRedisMessage) {
|
||||
System.out.println(((SimpleStringRedisMessage) msg).content());
|
||||
} else if (msg instanceof ErrorRedisMessage) {
|
||||
System.out.println(((ErrorRedisMessage) msg).content());
|
||||
} else if (msg instanceof IntegerRedisMessage) {
|
||||
System.out.println(((IntegerRedisMessage) msg).value());
|
||||
} else if (msg instanceof FullBulkStringRedisMessage) {
|
||||
System.out.println(getString((FullBulkStringRedisMessage) msg));
|
||||
} else if (msg instanceof ArrayRedisMessage) {
|
||||
for (RedisMessage child : ((ArrayRedisMessage) msg).children()) {
|
||||
printAggregatedRedisResponse(child);
|
||||
}
|
||||
} else {
|
||||
throw new CodecException("unknown message type: " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getString(FullBulkStringRedisMessage msg) {
|
||||
if (msg.isNull()) {
|
||||
return "(null)";
|
||||
}
|
||||
return msg.content().toString(CharsetUtil.UTF_8);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ EXAMPLE_MAP=(
|
||||
'objectecho-server:io.netty.example.objectecho.ObjectEchoServer'
|
||||
'quote-client:org.jboss.netty.example.qotm.QuoteOfTheMomentClient'
|
||||
'quote-server:org.jboss.netty.example.qotm.QuoteOfTheMomentServer'
|
||||
'redis-client:io.netty.example.redis.RedisClient'
|
||||
'securechat-client:io.netty.example.securechat.SecureChatClient'
|
||||
'securechat-server:io.netty.example.securechat.SecureChatServer'
|
||||
'telnet-client:io.netty.example.telnet.TelnetClient'
|
||||
|
Loading…
Reference in New Issue
Block a user