public static void Loop(Config config) { (Connection conn, int bufferSize, bool setMask) = config; // 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 incase disconnect while send thread is starting if (client == null) { return; } while (client.Connected) { // wait for message conn.sendPending.Wait(); conn.sendPending.Reset(); while (conn.sendQueue.TryDequeue(out ArrayBuffer msg)) { // check if connected before sending message if (!client.Connected) { Log.Info($"SendLoop {conn} not connected"); return; } SendMessage(stream, writeBuffer, msg, setMask, maskHelper); 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 { conn.Dispose(); maskHelper?.Dispose(); } }
public static void Loop(Config config) { (Connection conn, int bufferSize, bool setMask) = config; // 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"); 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"); 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 { conn.Dispose(); maskHelper?.Dispose(); } }
/// <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); }
static void SendMessage(Stream stream, byte[] buffer, ArrayBuffer msg, bool setMask, MaskHelper maskHelper) { int msgLength = msg.count; int sendLength = WriteHeader(buffer, msgLength, setMask); if (setMask) { sendLength = maskHelper.WriteMask(buffer, sendLength); } msg.CopyTo(buffer, sendLength); sendLength += msgLength; // dump before mask on Log.DumpBuffer("Send", buffer, 0, sendLength); if (setMask) { int messageOffset = sendLength - msgLength; MessageProcessor.ToggleMask(buffer, messageOffset, msgLength, buffer, messageOffset - Constants.MaskSize); } stream.Write(buffer, 0, sendLength); }