public void Write <T>(T message) { const int sizeSize = sizeof(int); const int codeSize = sizeof(byte); const int headerSize = sizeSize + codeSize; byte[] messageBody; long messageLength = 0; using (var memStream = new MemoryStream()) { // add a buffer to the start of the array to put the size and message code memStream.Position += headerSize; Serializer.Serialize(memStream, message); messageBody = memStream.GetBuffer(); messageLength = memStream.Position; } // check to make sure something was written, otherwise we'll have to create a new array if (messageLength == headerSize) { messageBody = new byte[headerSize]; } var messageCode = TypeToMessageCodeMap[typeof(T)]; var size = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)messageLength - headerSize + 1)); Array.Copy(size, messageBody, sizeSize); messageBody[sizeSize] = (byte)messageCode; if (PbcSocket.Send(messageBody, (int)messageLength, SocketFlags.None) == 0) { throw new RiakException("Failed to send data to server - Timed Out: {0}:{1}".Fmt(_server, _port)); } }
// read from socket async private Task <byte[]> SocketReadAsync(int size) { var source = new TaskCompletionSource <byte[]>(); var data = new byte[size]; // start reading PbcSocket.ReceiveTimeout = 0; int totalBytesReceived = 0; int lengthToReceive = size; // read in chunks as a continuation behaviour Action readChunkAsync = null; readChunkAsync = (() => { var startRead = PbcSocket.BeginReceive(data, totalBytesReceived, lengthToReceive, SocketFlags.None, null, 0); Task.Factory.FromAsync <int>(startRead, PbcSocket.EndReceive) .ContinueWith((Task <int> readTask) => { if (readTask.IsFaulted) { source.SetException(readTask.Exception); } else { if (readTask.Result == 0) { source.SetException( new RiakException("Unable to read data from the source stream - Timed Out.")); } else { // continue if necessary totalBytesReceived += readTask.Result; lengthToReceive -= readTask.Result; if (lengthToReceive > 0) { readChunkAsync(); } else { source.SetResult(data); } } } }); }); // start reading and give back delayed buffer task readChunkAsync(); return(source.Task); }
// write to socket async private Task SocketWriteAsync(byte[] data) { var source = new TaskCompletionSource <object>(); // start writing var maxBufferSize = 1024 * 4; var bytesToSend = data.Length; var position = 0; // write chunks as a continuation behaviour Action writeChunkAsync = null; writeChunkAsync = (() => { var startWrite = PbcSocket.BeginSend(data, position, Math.Min(bytesToSend, maxBufferSize), SocketFlags.None, null, 0); Task <int> .Factory.FromAsync(startWrite, PbcSocket.EndSend) .ContinueWith((Task <int> writeTask) => { if (writeTask.IsFaulted) { source.SetException(writeTask.Exception); } else { if (writeTask.Result == 0) { source.SetException( new RiakException("Failed to send data to server - Timed Out: {0}:{1}" .Fmt(_server, _port))); } else { // continue if necessary position += writeTask.Result; bytesToSend -= writeTask.Result; if (bytesToSend > 0) { writeChunkAsync(); } else { source.SetResult(new object()); } } } }); }); // start writing and give back deferred task writeChunkAsync(); return(source.Task); }
private byte[] ReceiveAll(byte[] resultBuffer) { int totalBytesReceived = 0; int lengthToReceive = resultBuffer.Length; while (lengthToReceive > 0) { int bytesReceived = PbcSocket.Receive(resultBuffer, totalBytesReceived, lengthToReceive, 0); if (bytesReceived == 0) { throw new RiakException("Unable to read data from the source stream - Timed Out."); } totalBytesReceived += bytesReceived; lengthToReceive -= bytesReceived; } return(resultBuffer); }
public void Write(MessageCode messageCode) { const int sizeSize = sizeof(int); const int codeSize = sizeof(byte); const int headerSize = sizeSize + codeSize; var messageBody = new byte[headerSize]; var size = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(1)); Array.Copy(size, messageBody, sizeSize); messageBody[sizeSize] = (byte)messageCode; if (PbcSocket.Send(messageBody, headerSize, SocketFlags.None) == 0) { throw new RiakException("Failed to send data to server - Timed Out: {0}:{1}".Fmt(_server, _port)); } }