0

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
        {

        }

    }
Bryan
  • 23
  • 7
  • i don’t see any issues with Starscream initialize. could be the issue with your server. or try commenting out pong delegate and disconnect func in deinit to cross check that view controller not force disconnecting. i been using this lib for about a year. it works great with some flaws – karthik Jan 24 '19 at 17:51

2 Answers2

0

All you need is a listening loop. Because this is a top down execution, so after you write the response, the tcp client listener stops. You can take a look at this implementation https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcplistener?view=netframework-4.7.2

Ryan Ho
  • 293
  • 1
  • 3
  • 14
0

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()
Bryan
  • 23
  • 7