C# WebSocket Bidirectional Reading/Writing in Threads

Demonstrates how to simultaneously read and write a websocket connection in C# with threads.



        // Read task
        static void ReadTask(Chilkat.WebSocket wsReader)
            {
            for (int i = 1; i <= 10; i++)
                {
                uint startTick = (uint)Environment.TickCount;
                bool receivedFinalFrame = false;
                int count = 0;

                while (!receivedFinalFrame)
                    {
                    if (!wsReader.ReadFrame())
                        {
                        Console.WriteLine(wsReader.LastErrorText);
                        Console.WriteLine("Read task failed.");
                        return;
                        }
                    receivedFinalFrame = wsReader.FinalFrame;
                    count++;
                    }

                uint endTick = (uint)Environment.TickCount;
                Console.WriteLine("Received: " + wsReader.GetFrameData());
                }

            Console.WriteLine("Read task is exiting");
            }

        // Write task
        static void WriteTask(Chilkat.WebSocket wsWriter)
            {
            char msg = 'A';

            for (int i = 1; i <= 10; i++)
                {
                if (!wsWriter.SendFrame(msg.ToString(), true))
                    {
                    Console.WriteLine(wsWriter.LastErrorText);
                    Console.WriteLine("Write task failed.");
                    return;
                    }
                msg++;
                }

            Console.WriteLine("Write task is exiting");
            }

        public static bool TestChilkatWebSocket()
            {
            string testName = "qa_websocket_chilkat_io_bidirectional";

            Chilkat.WebSocket wsReader = new Chilkat.WebSocket();
            Chilkat.WebSocket wsWriter = new Chilkat.WebSocket();
            Chilkat.Rest rest = new Chilkat.Rest();

            bool success = rest.Connect("websockets.chilkat.io", 80, false, false);
            if (!success) return Failed(testName, rest);

            if (!wsReader.UseConnection(rest)) return Failed(testName, wsReader);
            if (!wsReader.AddClientHeaders()) return Failed(testName, wsReader);
            if (rest.FullRequestNoBody("GET", "/wsChilkatEcho.ashx") == null) return Failed(testName, wsReader);
            if (!wsReader.ValidateServerHandshake()) return Failed(testName, wsReader);

            // Share the connection
            wsWriter.ShareConnection(wsReader);

            // Start threads
            Thread t1 = new Thread(() => ReadTask(wsReader));
            Thread t2 = new Thread(() => WriteTask(wsWriter));

            t1.Start();
            t2.Start();

            t1.Join();
            t2.Join();

            if (!wsWriter.SendClose(true, 1000, "Closing this websocket.")) return Failed(testName, wsWriter);
            if (!wsReader.ReadFrame()) return Failed(testName, wsReader);

            return Succeeded(testName);
            }

        // Helpers to simulate test outcome reporting
        static bool Failed(string testName, object obj)
        {
            if (obj is Chilkat.WebSocket) Console.WriteLine(((Chilkat.WebSocket)obj).LastErrorText);
            else if (obj is Chilkat.Rest) Console.WriteLine(((Chilkat.Rest)obj).LastErrorText);
            Console.WriteLine(testName + " failed.");
            return false;
        }

        static bool Succeeded(string testName)
        {
            Console.WriteLine(testName + " succeeded.");
            return true;
        }