When fixing #1064 I was looking at other parts of the stack and noticed there are at least a few other places where we could go directly toa/from UTF-8 but do not.
|
var json = JsonSerializer.Serialize(message, McpJsonUtilities.JsonContext.Default.JsonRpcMessage); |
|
LogTransportSendingMessageSensitive(Name, json); |
|
await _outputStream.WriteAsync(Encoding.UTF8.GetBytes(json), cancellationToken).ConfigureAwait(false); |
|
var line = await _inputReader.ReadLineAsync(shutdownToken).ConfigureAwait(false); |
|
if (string.IsNullOrWhiteSpace(line)) |
|
{ |
|
if (line is null) |
|
{ |
|
LogTransportEndOfStream(Name); |
|
break; |
|
} |
|
|
|
continue; |
|
} |
|
|
|
LogTransportReceivedMessageSensitive(Name, line); |
|
|
|
try |
|
{ |
|
if (JsonSerializer.Deserialize(line, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(JsonRpcMessage))) is JsonRpcMessage message) |
|
{ |
|
await WriteMessageAsync(message, shutdownToken).ConfigureAwait(false); |
|
} |
|
else |
|
{ |
|
LogTransportMessageParseUnexpectedTypeSensitive(Name, line); |
|
} |
|
} |
|
var json = JsonSerializer.Serialize(message, McpJsonUtilities.JsonContext.Default.JsonRpcMessage); |
|
|
|
LogTransportSendingMessageSensitive(Name, json); |
|
|
|
using var _ = await _sendLock.LockAsync(cancellationToken).ConfigureAwait(false); |
|
try |
|
{ |
|
// Write the message followed by a newline using our UTF-8 writer |
|
await _serverInput.WriteLineAsync(json).ConfigureAwait(false); |
|
if (await _serverOutput.ReadLineAsync(cancellationToken).ConfigureAwait(false) is not string line) |
|
{ |
|
LogTransportEndOfStream(Name); |
|
break; |
|
} |
|
|
|
if (string.IsNullOrWhiteSpace(line)) |
|
{ |
|
continue; |
|
} |
|
|
|
LogTransportReceivedMessageSensitive(Name, line); |
|
|
|
await ProcessMessageAsync(line, cancellationToken).ConfigureAwait(false); |
We do have a some places that try to avoid strings -
|
int maxByteCount = Encoding.UTF8.GetMaxByteCount(value.Length); |
|
Span<byte> buffer = writer.GetSpan(maxByteCount); |
|
Debug.Assert(buffer.Length >= maxByteCount); |
|
|
|
int bytesWritten = Encoding.UTF8.GetBytes(value, buffer); |
|
writer.Advance(bytesWritten); |
If folks agree we can make a pass at these and related types to avoid encoding to strings and go straight from UTF-8 bytes on the wire to serialized objects.
When fixing #1064 I was looking at other parts of the stack and noticed there are at least a few other places where we could go directly toa/from UTF-8 but do not.
csharp-sdk/src/ModelContextProtocol.Core/Server/StreamServerTransport.cs
Lines 77 to 79 in 27b5eb8
csharp-sdk/src/ModelContextProtocol.Core/Server/StreamServerTransport.cs
Lines 100 to 124 in 27b5eb8
csharp-sdk/src/ModelContextProtocol.Core/Client/StreamClientSessionTransport.cs
Lines 106 to 114 in 27b5eb8
csharp-sdk/src/ModelContextProtocol.Core/Client/StreamClientSessionTransport.cs
Lines 137 to 150 in 27b5eb8
We do have a some places that try to avoid strings -
csharp-sdk/src/Common/ServerSentEvents/SseEventWriterHelpers.cs
Lines 51 to 56 in 27b5eb8
If folks agree we can make a pass at these and related types to avoid encoding to strings and go straight from UTF-8 bytes on the wire to serialized objects.