0

I created a .NET class socket using a websocket server. When my browser tries to connect to socket on my program, I see that the method 'accept socket' is called very slow or seconds after my browser connects. I tried creating many connections but the socket accepts a websocket every second. I tried alchemy websocket too, results like my code.

After I used Miscrosoft websocket on IIS8, I noticed that the speed is pretty good.

I am not experimental.

My code (express)

class Connection
{
    byte[] buffer = new byte[1024];
    Socket socket;
    bool IsAuthencation;
    public Connection(Socket socket)
    {
        this.socket = socket;
        socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
    }

    void OnReceive(IAsyncResult result)
    {
        try
        {
            int count = socket.EndReceive(result);
            if (count != 0)
            {
                if (!IsAuthencation)
                {
                    byte[] tmp = new byte[count];
                    Array.Copy(buffer, 0, tmp, 0, count);
                    string Request = Encoding.UTF8.GetString(tmp);
                    if (Request.Contains("GET"))
                    {
                        if (!IsAuthencation)
                        {
                            int indexStart = Request.IndexOf("Sec-WebSocket-Key: ");
                            int indexEnd = Request.IndexOf("Sec-WebSocket-Version:");
                            string key = Request.Substring(indexStart + 19, indexEnd - indexStart - 21);
                            string magic = string.Concat(key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
                            string base64 = "";
                            using (SHA1 sha1 = SHA1.Create())
                            {
                                byte[] bufferMagic = sha1.ComputeHash(Encoding.UTF8.GetBytes(magic));
                                base64 = Convert.ToBase64String(bufferMagic);
                            }

                            Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
                                + "Connection: Upgrade" + Environment.NewLine
                                + "Upgrade: websocket" + Environment.NewLine
                                + "Sec-WebSocket-Accept: " + base64
                                + Environment.NewLine
                                + Environment.NewLine);
                            socket.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
                            IsAuthencation = true;
                        }
                    }
                }
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
            }
            else
            {
                // disconnect
            }
        }
        catch (Exception)
        {

        }
    }

    void OnSend(IAsyncResult result)
    {
        try
        {
            socket.EndSend(result);
        }
        catch (Exception)
        {

        }
    }

}
class Program
{
    static List<Connection> clients;
    static Socket socket;

    static void Main(string[] args)
    {
        clients = new List<Connection>();
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 30000);
        socket.Bind(endPoint);
        socket.Listen(0);
        socket.BeginAccept(new AsyncCallback(AcceptAsync), null);
        Console.ReadLine();
    }

    static void AcceptAsync(IAsyncResult result)
    {
        Console.WriteLine("a new connection");
        Socket s = socket.EndAccept(result);
        clients.Add(new Connection(s));
        socket.BeginAccept(new AsyncCallback(AcceptAsync), null);
    }


}

you can try command javascript var socket= new WebSocket("ws://localhost:30000"), i not see a problem in my code. Thanks

Charles
  • 50,943
  • 13
  • 104
  • 142
tuannv
  • 1
  • 2

1 Answers1

0

You have to accept the socket, and handle it asynchronously, and then back to accepting more sockets straightaway.

UPDATE

After seeing your code, it seems you are accepting connections asynchronously. How are you creating those test connections? If you are creating too many you are maybe saturating the app.

I think I see the problem, why are you setting the socket backlog to 0? Read this answer from SO.

Try to put a bigger value: socket.Listen(100);

Community
  • 1
  • 1
vtortola
  • 34,709
  • 29
  • 161
  • 263
  • i edit code on topic, you can help check error logic in code? – tuannv Apr 15 '14 at 10:40
  • i send command on brower chrome, you use chrome, express f12, click to tab console, write command var socket = new WebSocket("ws://localhost:30000") – tuannv Apr 15 '14 at 11:14
  • i see very slow although i change to socket.Listen(100). result test of you? – tuannv Apr 15 '14 at 11:39