【问题标题】:Connecting to Redis server with NSStream in Swift在 Swift 中使用 NSStream 连接到 Redis 服务器
【发布时间】:2015-08-11 21:40:29
【问题描述】:

大家好,标题提到我正在尝试以 Swift 语言从我的 Redis 服务器发送和接收数据。我已经做了很多研究,但我无法找到关于这个主题的好答案,我最接近的是 NSStream 或一些 Github 项目(其中大部分代码损坏),我一直在尝试创建一个解决了3天了,求大神帮忙。

Redis 在端口 6379 上的连接要求:

  • TCP
  • Telnet(我的最爱)

问题:

  1. App Delegate 崩溃线程 1:EXC_BAD_ACCESS(code=1, address=XXXXXXXX) 有时
  2. 无数据返回

带初始化的类 (Redis): 最接近我可以使用 NSStream 理解该过程的水平,但这并没有在我的对话框中打印任何要返回的内容,我无法弄清楚出了什么问题。 p>

class Redis: NSObject, NSStreamDelegate {

     //Intilizing Stream & Requirement
     var endPoint: CFString?
     var onPort: UInt32?
     var inputStream: NSInputStream?
     var outputStream: NSOutputStream?

服务器连接功能:

    func serverConnection(endPoint: CFString, onPort: UInt32){

        //Streams Init
        let Host: CFString = endPoint
        let Port: UInt32 = onPort
        var readStream: Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        //Bind Streams to Host and Port
        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, Host, Port, &readStream, &writeStream)

        //Cast CFStream to NSStreams
        inputStream = readStream!.takeRetainedValue()
        outputStream = writeStream!.takeRetainedValue()

        //Assign Delegate
        inputStream!.delegate = self
        outputStream!.delegate = self

        //Schadule Run-loop
        inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
        outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

        //Open Connection
        inputStream!.open()
        outputStream!.open()


    }

流:应用午餐后,我收到一个应用委托错误SOMETIMES

线程 1:EXC_BAD_ACCESS(code=1, address=XXXXXXXX)

    func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
        if aStream === inputStream {
            switch eventCode {
            case NSStreamEvent.ErrorOccurred:
                //Print Available Errors
                print("Error: \(aStream.streamError?.description)")
                break
            case NSStreamEvent.OpenCompleted:
                //Connection Succeed
                print("Connection Complete \(aStream.description)")
                break
            case NSStreamEvent.HasBytesAvailable:
                //Server Respond
                var buffer = [UInt8](count: 8, repeatedValue: 0)
                while inputStream?.hasBytesAvailable != nil {
                    let result: Int = (inputStream?.read(&buffer, maxLength: buffer.count))!
                    print(result)
                    print(buffer)
                }
                break
            default:
                break

            }
        }

        if aStream === outputStream {
            switch eventCode {
            case NSStreamEvent.ErrorOccurred:
                //Print Available Errors
                print("Error: \(aStream.streamError?.description)")
                break
            case NSStreamEvent.OpenCompleted:
                //Connection Succeed
                print("Connection Complete \(aStream.description)")
                break
            case NSStreamEvent.HasSpaceAvailable:
                //Ready to Send more Dat
                print("HasSpaceAvailable \(aStream.description)")
                break
            default:
                break

            }
        }

    }

使用 Ping 进行服务器测试:返回应该是 PONG

func Ping(){
    let Command: NSString = NSString(format: "Ping /n", String(endPoint))
    let data: NSData = NSData(data: Command.dataUsingEncoding(NSUTF8StringEncoding)!)
    outputStream!.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
}

【问题讨论】:

    标签: ios swift sockets redis nsstream


    【解决方案1】:

    感谢 GCDAsyncSocket,我能够使用 Swift 2 创建 Redis 连接解决方​​案。如果有人有兴趣下载,我还在 Github 上为 Redis 开发全套框架。

    Redis 类:必须包含GCDAsyncSocketDelegate

    import Foundation
    class Redis: NSObject,  GCDAsyncSocketDelegate {
    
        //Alloc GCDAsyncSocket
        var Socket: GCDAsyncSocket?
    
        /*============================================================
        // Server Open Connection
        ============================================================*/
        func server(endPoint: String, onPort: UInt16){
    
            //Check For Socket Condition
            if !(Socket != nil) {
    
                //Assign Delegeate to Self Queue
                Socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    
            }
    
            var err: NSError?
    
            /*============================================================
            GCDAsyncSocket ConnectToHost Throw Error so you must handle 
            this with Try [Try!], do, Catch.
            ============================================================*/
    
            do{
                //Assign Function Constants
                try Socket!.connectToHost(endPoint, onPort: onPort)
            }catch {
                //Error
                print(err)
            }
    
            //Read Send Data
            Socket?.readDataWithTimeout(2, tag: 1)
        }
    
    
        //Server Confirmation
        func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) {
            print("Connected to Redis!")
        }
    
        /*============================================================
        // Read Data From Redis Server [NSUTF8StringEncoding]
        ============================================================*/
    
        func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
            let Recieved: NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!
            print(Recieved)
        }
    
        /*===============================================================
        // Send Command [I Will create Full SET and Upload it to Github]
        =================================================================*/
    
        func Command(Command: String){
            let request: String = Command + "\r\n"
            let data: NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!
            Socket!.writeData(data, withTimeout: 1.0, tag: 0)
    
        }
    
    }
    

    调用方法,方法是创建一个 Redis 类的常量。

     let redisServer = Redis()
     redisServer.server("XX.XX.XXX.XXX", onPort: 6379)
     redisServer.Command("Ping") //Return Should be **PONG**
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2012-03-17
      • 2021-06-23
      • 2013-02-25
      • 2017-03-01
      • 1970-01-01
      • 2019-10-18
      相关资源
      最近更新 更多