diff --git a/docs/src/reference/docbook/appendix/appendix-command-reference.xml b/docs/src/reference/docbook/appendix/appendix-command-reference.xml
index a8c5aeb66..f00bd788e 100644
--- a/docs/src/reference/docbook/appendix/appendix-command-reference.xml
+++ b/docs/src/reference/docbook/appendix/appendix-command-reference.xml
@@ -24,7 +24,7 @@
BRPOPXBRPOPLPUSHXCLIENT GETNAME-
- CLIENT KILL-
+ CLIENT KILLXCLIENT LIST-CLIENT SETNAME-CONFIG GETX
diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
index 3eaba7053..b4f0addc2 100644
--- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java
@@ -2191,6 +2191,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection {
return this.delegate.time();
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[])
+ */
+ @Override
+ public void killClient(String host, int port) {
+ this.delegate.killClient(host, port);
+ }
+
/**
* Specifies if pipelined and tx results should be deserialized to Strings. If false, results of
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the underlying connection
diff --git a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java
index d3f7fff39..3e34dffba 100644
--- a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java
+++ b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java
@@ -161,4 +161,14 @@ public interface RedisServerCommands {
* @since 1.1
*/
Long time();
+
+ /**
+ * Closes a given client connection identified by {@literal ip:port}.
+ *
+ * @param host of connection to close.
+ * @param port of connection to close
+ * @since 1.3
+ */
+ void killClient(String host, int port);
+
}
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
index 5c5216798..3af0cd6fa 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
@@ -2808,6 +2808,26 @@ public class JedisConnection implements RedisConnection {
return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1));
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.redis.connection.RedisServerCommands#killClient(byte[])
+ */
+ @Override
+ public void killClient(String host, int port) {
+
+ Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
+
+ if (isQueueing() || isPipelined()) {
+ throw new UnsupportedOperationException("'CLIENT KILL' is not supported in transaction / pipline mode.");
+ }
+
+ try {
+ this.jedis.clientKill(String.format("%s:%s", host, port));
+ } catch (Exception e) {
+ throw convertJedisAccessException(e);
+ }
+ }
+
/**
* Specifies if pipelined results should be converted to the expected data type. If false, results of
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Jedis driver
diff --git a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
index bfb8ae347..26bfb5d8e 100644
--- a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
@@ -1185,4 +1185,9 @@ public class JredisConnection implements RedisConnection {
public Long time() {
throw new UnsupportedOperationException("The 'TIME' command is not supported by the JRedis driver.");
}
+
+ @Override
+ public void killClient(String host, int port) {
+ throw new UnsupportedOperationException("The 'CLIENT KILL' command is not supported by the JRedis driver.");
+ }
}
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java
index ce7c628f1..4b1ac6a65 100644
--- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java
@@ -2903,6 +2903,23 @@ public class LettuceConnection implements RedisConnection {
return Converters.toTimeMillis(new String(result.get(0)), new String(result.get(1)));
}
+ @Override
+ public void killClient(String host, int port) {
+
+ Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
+
+ String client = String.format("%s:%s", host, port);
+ try {
+ if (isPipelined()) {
+ pipeline(new LettuceStatusResult(getAsyncConnection().clientKill(client)));
+ return;
+ }
+ getConnection().clientKill(client);
+ } catch (Exception e) {
+ convertLettuceAccessException(e);
+ }
+ }
+
/**
* Specifies if pipelined and transaction results should be converted to the expected data type. If false, results of
* {@link #closePipeline()} and {@link #exec()} will be of the type returned by the Lettuce driver
diff --git a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
index f55d06db5..2849bbf99 100644
--- a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
@@ -2222,6 +2222,24 @@ public class SrpConnection implements RedisConnection {
return SrpConverters.toTimeAsLong(reply.data());
}
+ @Override
+ public void killClient(String host, int port) {
+
+ Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
+
+ String client = String.format("%s:%s", host, port);
+ try {
+ if (isPipelined()) {
+ pipeline(new SrpStatusResult(pipeline.client_kill(client)));
+ return;
+ }
+
+ this.client.client_kill(client);
+ } catch (Exception e) {
+ throw convertSrpAccessException(e);
+ }
+ }
+
private List