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>
|
<artifactId>netty-codec-memcache</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-codec-redis</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>netty-codec-socks</artifactId>
|
<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'
|
'objectecho-server:io.netty.example.objectecho.ObjectEchoServer'
|
||||||
'quote-client:org.jboss.netty.example.qotm.QuoteOfTheMomentClient'
|
'quote-client:org.jboss.netty.example.qotm.QuoteOfTheMomentClient'
|
||||||
'quote-server:org.jboss.netty.example.qotm.QuoteOfTheMomentServer'
|
'quote-server:org.jboss.netty.example.qotm.QuoteOfTheMomentServer'
|
||||||
|
'redis-client:io.netty.example.redis.RedisClient'
|
||||||
'securechat-client:io.netty.example.securechat.SecureChatClient'
|
'securechat-client:io.netty.example.securechat.SecureChatClient'
|
||||||
'securechat-server:io.netty.example.securechat.SecureChatServer'
|
'securechat-server:io.netty.example.securechat.SecureChatServer'
|
||||||
'telnet-client:io.netty.example.telnet.TelnetClient'
|
'telnet-client:io.netty.example.telnet.TelnetClient'
|
||||||
|
Loading…
Reference in New Issue
Block a user