Подключение к серверу Redis с помощью NSStream в Swift

Привет всем, как упоминание в заголовке. Я пытаюсь отправить и получить данные с моего сервера Redis на быстром языке. Я сделал много исследований, и я не могу найти хороший ответ по этой теме, самое близкое, к которому я пришел, это NSStream или несколько проектов Github (большинство из них с неработающим кодом), я пытался создать решение в течение 3 дней, пожалуйста, кто-нибудь, помогите.

Требование к соединению для Redis на порту 6379:

  • TCP
  • Telnet (мой любимый)

Проблемы:

  1. Сбой делегата приложения 1: EXC_BAD_ACCESS(code=1, address=XXXXXXXX) ИНОГДА
  2. Нет возврата данных

Класс с инициализацией (Redis): ближе всего я могу добраться до уровня, где я понимаю процедуру с NSStream, но опять же, это ничего не печатает для возврата в моем диалоге, и я не могу понять, что не так.

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()


    }

Поток: после обеда приложения я получаю ошибку делегата приложения

Поток 1: EXC_BAD_ACCESS(код =1, адрес =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)
}

1 ответ

Решение

Благодаря GCDAsyncSocket мне удалось создать решение для подключения Redis с помощью Swift 2. Я также работаю над Full set Framework на Github для Redis, если кто-то заинтересован в загрузке.

Redis Class: Вы должны включить 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**
Другие вопросы по тегам