How to create a custom websocket client in iOS, to send and receive JSON data?

750 views Asked by At

I wanted to connect to a server, ws://12.526.712.67:8000/joker and was told to establish a connection, and check for success message, using WEBSOCKETS.Then I had to post a JSON data along with the next request and get a JSON response as a result of it. I am not supposed to use any third party frameworks. So I got a sample code to get this done,

class Handler :NSObject, StreamDelegate {


var inputStream: InputStream?
var outputStream: OutputStream?
var status = false;
var output = ""
var bufferSize = 1024;
var onComing:OnComing!


func connect(host: String, port: Int, onComing:@escaping OnComing) {

    Stream.getStreamsToHost(withName: host, port: port, inputStream: &inputStream, outputStream: &outputStream)
    if inputStream != nil && outputStream != nil {

        inputStream!.delegate = self
        outputStream!.delegate = self
        self.onComing = onComing

        inputStream!.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
        outputStream!.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)

        inputStream!.open()
        outputStream!.open()

        print("successfully connected")
    }
    else {
        print("connection unsuccessful")
    }
}

func stream(_ aStream: Stream, handle eventCode: Stream.Event)

{
    if aStream === inputStream {
        switch eventCode {
        case Stream.Event.errorOccurred:
            print("input: ErrorOccurred: \(String(describing: aStream.streamError?.localizedDescription))")
            break
        case Stream.Event.openCompleted:
            print("input: OpenCompleted")
            break
        case Stream.Event.hasBytesAvailable:
            print("input: HasBytesAvailable")
            print(Stream.Event.hasBytesAvailable)
            print(Stream.Event.hasBytesAvailable.rawValue)
            var buffer = [UInt8](repeating: 0, count: 4096)
            while (inputStream?.hasBytesAvailable)!{
                let len = inputStream?.read(&buffer, maxLength: buffer.count)
                if(len! > 0){
                    let output = NSString(bytes: &buffer, length: len!, encoding: String.Encoding.utf8.rawValue)
                    if (output != ""){
                        print("server said: %@", output!)
                    }
                } else {
                    print("empty string from stream")
                }
            }
            break
        case Stream.Event.hasSpaceAvailable:
            print("input: hasSpaceAvailable")
            break
        default:
            break
        }
    }
    else {
        print("unknown stuff happened")
    }
}
func disconnect() {
    if let stream = self.inputStream {
        stream.close();
        stream.remove(from: RunLoop.current, forMode: RunLoopMode.commonModes);
    }
    if let stream = self.outputStream {
        stream.close();
        stream.remove(from: RunLoop.current, forMode: RunLoopMode.commonModes);
    }
    self.inputStream = nil;
    self.outputStream = nil;
}
func read() {
    output = ""
    var buffer = [UInt8](repeating: 0, count: bufferSize)
    while (self.inputStream!.hasBytesAvailable) {
        let bytesRead: Int = inputStream!.read(&buffer, maxLength: buffer.count)
        if bytesRead >= 0 {
            output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding: String.Encoding.ascii.rawValue)! as String
        } else {
            print("# Stream read() error")
        }
    }
    self.onComing(output)
}

func write(message:String) {
    let data = message.data(using: .utf8)!
    do {
        if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
        {
            print(jsonArray)
            let encodedDataArray = [UInt8]("\(jsonArray)\n".utf8)
            self.outputStream?.write(encodedDataArray, maxLength: encodedDataArray.count)

        } else {
            print("bad json")
        }
    } catch let error as NSError {
        print(error)
    }
}}

I triggered this class using the method,

Handler.connect(host: "12.526.712.67", port: 8000, onComing: {_ in
    print(OnComing.self)})

I'm getting connection success in my delegate response, but then when I pass the json data as input, I'm getting,

HTTP/1.1 400 
Transfer-Encoding: chunked
Date: Fri, 16 Mar 2018 09:00:31 GMT
Connection: close

What am I doing wrong?I couldn't get the JSON response or any status message, the "server said: %@"part is always empty, why is it so? Please do help me to sort this out.

0

There are 0 answers