Search code examples
c#iosswiftstarscream

iOS websocket connection instant disconnects


I am trying to get a websocket connection between an iOS Client (iPad Air 2) and my C# Server.

On iOS I'm using Starscream (https://github.com/daltoniam/Starscream) for websocket connections. But right after I successfully connect to my server, it automatically disconnects. The Sec-WebSocket-Accept are the same on both sides. I am guessing that the error is in my C# server, but i can't figure out what exactly is wrong.

Here my iOS code:

class ViewController: UIViewController {

var socket : WebSocket!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    socket = WebSocket(url: URL(string: "ws://192.168.188.35:80")!)
    socket.connect()
    socket.pongDelegate = self
    socket.advancedDelegate = self

}


deinit {
    socket.disconnect(forceTimeout: 0, closeCode: 0)
    socket.delegate = nil
}

}

extension ViewController: WebSocketAdvancedDelegate {
func websocketDidConnect(socket: WebSocket) {
    print("connect")
}

func websocketDidDisconnect(socket: WebSocket, error: Error?) {
    print("disconnect")
}

func websocketDidReceiveMessage(socket: WebSocket, text: String, response: WebSocket.WSResponse) {
    print("receivedMessage")
}

func websocketDidReceiveData(socket: WebSocket, data: Data, response: WebSocket.WSResponse) {
    print("receivedData")
}

func websocketHttpUpgrade(socket: WebSocket, request: String) {
    print("httpUpgradeRequest")
    print(request)
}

func websocketHttpUpgrade(socket: WebSocket, response: String) {
    print("httpUpgradeResponse")
    print(response)
}

}

And here is my C# server:

public TcpListener server;

    public MainWindow()
    {
        server = new TcpListener(IPAddress.Parse("192.168.188.35"), 80);

        server.Start();
        Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);

        TcpClient client = server.AcceptTcpClient();

        Console.WriteLine("A client connected.");

        NetworkStream stream = client.GetStream();


        while (client.Available < 3)
        {
            // wait for enough bytes to be available
        }

        Byte[] bytes = new Byte[client.Available];

        stream.Read(bytes, 0, bytes.Length);

        //translate bytes of request to string
        String data = Encoding.UTF8.GetString(bytes);

        if (Regex.IsMatch(data, "^GET"))
        {
            const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker

            Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol
                + "Connection: Upgrade" + eol
                + "Upgrade: websocket" + eol
                + "Sec-WebSocket-Accept: " + Convert.ToBase64String(
                    System.Security.Cryptography.SHA1.Create().ComputeHash(
                        Encoding.UTF8.GetBytes(
                            new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
                        )
                    )
                ) + eol
                + eol);

            stream.Write(response, 0, response.Length);
        }
        else
        {

        }

    }

Solution

  • I found the problem, it was inside my C# Server: After a client connected and the Handshake succeeded, you have to call

    server.AcceptSocket(); //or server.AcceptSocketAsync()