private void WriteValue(ref MessagePackWriter writer, BufferPoolBufferWriter bufferWriter, object item) { if (item == null) { writer.WriteNil(); } else { //MessagePackSerializer.Serialize(item.GetType(), ref writer, item); writer.Flush(); MessagePackSerializer.Serialize(item.GetType(), bufferWriter, item); } }
public BufferSegment EncodeMessage(Message message) { var memBuffer = BufferPool.Get(256, true); var stream = new BufferPoolMemoryStream(memBuffer, 0, memBuffer.Length, true, true, false, true); // Write 5 bytes for placeholder for length prefix stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte(0); var bufferWriter = new BufferPoolBufferWriter(stream); var writer = new MessagePackWriter(bufferWriter); switch (message.type) { case MessageTypes.StreamItem: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streamitem-message-encoding-1 // [2, Headers, InvocationId, Item] writer.WriteArrayHeader(4); writer.Write(2); WriteHeaders(ref writer); WriteString(ref writer, message.invocationId); WriteValue(ref writer, bufferWriter, message.item); break; case MessageTypes.Completion: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#completion-message-encoding-1 // [3, Headers, InvocationId, ResultKind, Result?] byte resultKind = (byte)(!string.IsNullOrEmpty(message.error) ? /*error*/ 1 : message.result != null ? /*non-void*/ 3 : /*void*/ 2); writer.WriteArrayHeader(resultKind == 2 ? 4 : 5); writer.Write(3); WriteHeaders(ref writer); WriteString(ref writer, message.invocationId); writer.Write(resultKind); if (resultKind == 1) // error { WriteString(ref writer, message.error); } else if (resultKind == 3) // non-void { WriteValue(ref writer, bufferWriter, message.result); } break; case MessageTypes.Invocation: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#invocation-message-encoding-1 // [1, Headers, InvocationId, NonBlocking, Target, [Arguments], [StreamIds]] case MessageTypes.StreamInvocation: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#streaminvocation-message-encoding-1 // [4, Headers, InvocationId, Target, [Arguments], [StreamIds]] writer.WriteArrayHeader(message.streamIds != null ? 6 : 5); writer.Write((int)message.type); WriteHeaders(ref writer); WriteString(ref writer, message.invocationId); WriteString(ref writer, message.target); writer.WriteArrayHeader(message.arguments != null ? message.arguments.Length : 0); if (message.arguments != null) { for (int i = 0; i < message.arguments.Length; ++i) { WriteValue(ref writer, bufferWriter, message.arguments[i]); } } if (message.streamIds != null) { writer.WriteArrayHeader(message.streamIds.Length); for (int i = 0; i < message.streamIds.Length; ++i) { WriteValue(ref writer, bufferWriter, message.streamIds[i]); } } break; case MessageTypes.CancelInvocation: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#cancelinvocation-message-encoding-1 // [5, Headers, InvocationId] writer.WriteArrayHeader(3); writer.Write(5); WriteHeaders(ref writer); WriteString(ref writer, message.invocationId); break; case MessageTypes.Ping: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#ping-message-encoding-1 // [6] writer.WriteArrayHeader(1); writer.Write(6); break; case MessageTypes.Close: // https://github.com/aspnet/AspNetCore/blob/master/src/SignalR/docs/specs/HubProtocol.md#close-message-encoding-1 // [7, Error, AllowReconnect?] writer.WriteArrayHeader(string.IsNullOrEmpty(message.error) ? 1 : 2); writer.Write(7); if (!string.IsNullOrEmpty(message.error)) { WriteString(ref writer, message.error); } break; } writer.Flush(); // get how much bytes got written to the buffer. This includes the 5 placeholder bytes too. int length = (int)stream.Position; // this is the length without the 5 placeholder bytes int contentLength = length - 5; // get the stream's internal buffer. We set the releaseBuffer flag to false, so we can use it safely. var buffer = stream.GetBuffer(); // add varint length prefix byte prefixBytes = GetRequiredBytesForLengthPrefix(contentLength); WriteLengthAsVarInt(buffer, 5 - prefixBytes, contentLength); // return with the final segment return(new BufferSegment(buffer, 5 - prefixBytes, contentLength + prefixBytes)); }