美文网首页
SwiftNIO-连接Redis(一)

SwiftNIO-连接Redis(一)

作者: 小天枢丶 | 来源:发表于2018-06-14 10:02 被阅读0次

上星期用SwiftNIO写了一套程序,然后需要用到redis做缓存,然后就去GitHub上找了一下发现有一个开源库,但是用的时候发现有Bug,向作者提了issue之后至今没有修复... 所以就自己动手造了个轮子,顺便学习一下。

要做redis客户端的话有两个东西必须要了解,RESP协议redis命令

简单介绍RESP

  • 单行字符串(Simple Strings), 开头字符为:'+' "+OK\r\n"
  • 错误信息(Errors),开头字符为:'-' "-Error message\r\n"
  • 整形数字(Integers),开头字符为:':' ":0\r\n"
  • 多行字符串(Bulk Strings),开头字符为:'$' "$6\r\nfoobar\r\n"
  • 数组(Arrays),开头字符为:'*' "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"

需要注意的是不管是发送的命令还是收到来自redis服务端的回复,都是以\r\n结尾。

Java那边的叫Jedis,用Netty写的叫Nedis,那么我就把这个命名为Sedis了!

首先创建一个struct,用来存储连接信息:

struct SedisOptions {
    let prot: Int
    let host: String
    var password: String?
    var database: Int?
}

然后创建SedisClient类:

这个类里面需要根据SedisOptions的信息来创建连接,包括身份验证。

class SedisClient {
    private let options: SedisOptions
    private var bootstrap: ClientBootstrap?
    private var loopGroup: EventLoopGroup!
    
    init(options: SedisOptions) {
        self.options = options
        
        loopGroup = MultiThreadedEventLoopGroup(numThreads: System.coreCount)
        bootstrap = ClientBootstrap(group: loopGroup)
            .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET),
                                                 SO_REUSEADDR), value: 1)
            .channelInitializer({ (channel) -> EventLoopFuture<Void> in
                    channel.pipeline.add(handler: RESPHandler())
            })
        
    }
    
    private func _connect() -> EventLoopFuture<Channel> {
        assert(bootstrap != nil, "init failure")
        
        return bootstrap!.connect(host: options.host, port: options.prot)
    }
}

之前写了一遍用SwiftNIO建立UDP通讯的,用的是DatagramBootstrap,我们这里需要当作客户端连接,所以用的是ClientBootstrap

最后加上一个RESPHandler

class RESPHandler: ChannelDuplexHandler {
    typealias InboundIn = ByteBuffer
    
    func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
        var value = unwrapInboundIn(data)
        print(value.readString(length: value.writerIndex))
    }
}

这里接收到服务端回复后先不做任何操作直接输出。

现在在SedisClientinit方法末尾加上一段测试代码测试是否能正常通讯

init(options: SedisOptions) {
        self.options = options
        
        loopGroup = MultiThreadedEventLoopGroup(numThreads: System.coreCount)
        bootstrap = ClientBootstrap(group: loopGroup)
            .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET),
                                                 SO_REUSEADDR), value: 1)
            .channelInitializer({ (channel) -> EventLoopFuture<Void> in
                    channel.pipeline.add(handler: RESPHandler())
            })
        
        let channel = try? _connect().wait()
        let command = "set a 1\r\n".utf8
        var byteBuffer = ByteBufferAllocator().buffer(capacity: command.count)
        byteBuffer.write(bytes: command)
        channel?.writeAndFlush(byteBuffer, promise: nil)
        try? channel?.closeFuture.wait()
    }

测试运行

let sdies = SedisClient(options: SedisOptions(prot: 6379, host: "127.0.0.1", password: nil, database: 0))

可以看到控制台输出

Optional("+OK\r\n")

至此,第一部分就已经finish

相关文章

  • SwiftNIO-连接Redis(一)

    上星期用SwiftNIO写了一套程序,然后需要用到redis做缓存,然后就去GitHub上找了一下发现有一个开源库...

  • Redis学习之路(9)命令 -Redis 连接

    Redis 连接 Redis 连接命令主要是用于连接 redis 服务。 Redis 连接命令

  • redis常用命令

    查看redis进程 连接redis redis启动 redis停止 redis查看配置文件 redis查看最大连接...

  • hyperf遇到的坑redis连接报错

    redis连接方式 redis 代理连接池 实际是继承了redis客户端代理封装成连接池 多个连接的redis

  • Redis数据库基础

    一、Redis连接 1. redis-cli 或者 redis-cli -p 6379 //连接redis数据库...

  • springboot 2.x整合redis

    引入redis依赖 设置连接redis的配置 Redis配置 配置redis连接 开始使用

  • redis的使用,以及耗时定位

    一、连接redis 本地连接 连接远程服务器的时候使用 二、redis线程池 三、管道 redis-py默认在执行...

  • Redis 连接

    Redis 连接 Redis 连接命令主要是用于连接 redis 服务。 实例 以下实例演示了客户端如何通过密码验...

  • Python操作Redis

    Python操作Redis 连接 Redis **import **redis r = redis.StrictR...

  • Redis 连接

    Redis 连接命令主要是用于连接 redis 服务。实例以下实例演示了客户端如何通过密码验证连接到 redis ...

网友评论

      本文标题:SwiftNIO-连接Redis(一)

      本文链接:https://www.haomeiwen.com/subject/wvmeeftx.html