Exemplo n.º 1
0
        public static void Loop(Config config)
        {
            (Connection conn, int bufferSize, bool setMask) = config;

            Profiler.BeginThreadProfiling("SimpleWeb", $"SendLoop {conn.connId}");

            // create write buffer for this thread
            byte[]     writeBuffer = new byte[bufferSize];
            MaskHelper maskHelper  = setMask ? new MaskHelper() : null;

            try
            {
                TcpClient client = conn.client;
                Stream    stream = conn.stream;

                // null check in case disconnect while send thread is starting
                if (client == null)
                {
                    return;
                }

                while (client.Connected)
                {
                    // wait for message
                    conn.sendPending.Wait();
                    // wait for 1ms for mirror to send other messages
                    if (SendLoopConfig.sleepBeforeSend)
                    {
                        Thread.Sleep(1);
                    }
                    conn.sendPending.Reset();

                    if (SendLoopConfig.batchSend)
                    {
                        int offset = 0;
                        while (conn.sendQueue.TryDequeue(out ArrayBuffer msg))
                        {
                            // check if connected before sending message
                            if (!client.Connected)
                            {
                                Log.Info($"SendLoop {conn} not connected");
                                msg.Release();
                                return;
                            }

                            int maxLength = msg.count + Constants.HeaderSize + Constants.MaskSize;

                            // if next writer could overflow, write to stream and clear buffer
                            if (offset + maxLength > bufferSize)
                            {
                                stream.Write(writeBuffer, 0, offset);
                                offset = 0;
                            }

                            offset = SendMessage(writeBuffer, offset, msg, setMask, maskHelper);
                            msg.Release();
                        }

                        // after no message in queue, send remaining messages
                        // don't need to check offset > 0 because last message in queue will always be sent here

                        stream.Write(writeBuffer, 0, offset);
                    }
                    else
                    {
                        while (conn.sendQueue.TryDequeue(out ArrayBuffer msg))
                        {
                            // check if connected before sending message
                            if (!client.Connected)
                            {
                                Log.Info($"SendLoop {conn} not connected");
                                msg.Release();
                                return;
                            }

                            int length = SendMessage(writeBuffer, 0, msg, setMask, maskHelper);
                            stream.Write(writeBuffer, 0, length);
                            msg.Release();
                        }
                    }
                }

                Log.Info($"{conn} Not Connected");
            }
            catch (ThreadInterruptedException e) { Log.InfoException(e); }
            catch (ThreadAbortException e) { Log.InfoException(e); }
            catch (Exception e)
            {
                Log.Exception(e);
            }
            finally
            {
                Profiler.EndThreadProfiling();
                conn.Dispose();
                maskHelper?.Dispose();
            }
        }
Exemplo n.º 2
0
        /// <returns>new offset in buffer</returns>
        static int SendMessage(byte[] buffer, int startOffset, ArrayBuffer msg, bool setMask, MaskHelper maskHelper)
        {
            int msgLength = msg.count;
            int offset    = WriteHeader(buffer, startOffset, msgLength, setMask);

            if (setMask)
            {
                offset = maskHelper.WriteMask(buffer, offset);
            }

            msg.CopyTo(buffer, offset);
            offset += msgLength;

            // dump before mask on
            Log.DumpBuffer("Send", buffer, startOffset, offset);

            if (setMask)
            {
                int messageOffset = offset - msgLength;
                MessageProcessor.ToggleMask(buffer, messageOffset, msgLength, buffer, messageOffset - Constants.MaskSize);
            }

            return(offset);
        }