private void ReadSocket(SyncStreamHandler syncStreamHandler) { // 60 seconds, client should echo to this service every 30 seconds. // It will have only once chance to miss, otherwise, connection will be dropped. this._RemoteClient.ReceiveTimeout = 60000; byte[] head = new byte[8]; int bR = 0; try { do { // Read Head bR += syncStreamHandler.ReadUnsafe(head, bR, head.Length - bR); if (bR == 0) { return; // if it is 0 that means, connection is zombie. Just close it. } if (bR != head.Length) { continue; } this.Consume(head, syncStreamHandler); bR = 0; } while (true); } catch (Exception ex) { // Skip SocketExceptions if (ex is IOException && ex.InnerException is SocketException) { return; } Basics.Console.Push("SYSTEM ERROR", ex.Message, ex.ToString(), false, true, type: Basics.Console.Type.Error); } }
private void Consume(byte[] contentHead, SyncStreamHandler syncStreamHandler) { // 8 bytes first 5 bytes are requestId, remain 3 bytes are request length. Request length can be max 15Mb long head = BitConverter.ToInt64(contentHead, 0); long requestId = head >> 24; int contentSize = (int)(head & 0xFFFFFF); byte[] buffer = new byte[1024]; Stream contentStream = null; try { contentStream = new MemoryStream(); do { int readLength = buffer.Length; if (contentSize < readLength) { readLength = contentSize; } int bR = syncStreamHandler.ReadUnsafe(buffer, 0, readLength); contentStream.Write(buffer, 0, bR); contentSize -= bR; } while (contentSize > 0); byte[] messageBlock = ((MemoryStream)contentStream).ToArray(); this._Handler.ProcessAsync(requestId, messageBlock); } finally { contentStream?.Close(); } }