Files
sqltoolsservice/external/Microsoft.SqlTools.Hosting.v2/Protocol/MessageWriter.cs
Karl Burtram ccf95aed77 Move unused forked code to external directory (#1192)
* Move unused forked code to external directory

* Fix SLN build errors

* Add back resource provider core since it's referenced by main resource provider project

* Update PackageProjects step of pipeline
2021-04-16 15:33:35 -07:00

61 lines
2.3 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SqlTools.Hosting.Utility;
namespace Microsoft.SqlTools.Hosting.Protocol
{
public class MessageWriter
{
private const string ContentLength = "Content-Length: ";
private const string ContentType = "Content-Type: application/json";
private const string HeaderSeparator = "\r\n";
private const string HeaderEnd = "\r\n\r\n";
private readonly Stream outputStream;
private readonly AsyncLock writeLock = new AsyncLock();
public MessageWriter(Stream outputStream)
{
Validate.IsNotNull("streamWriter", outputStream);
this.outputStream = outputStream;
}
public virtual async Task WriteMessage(Message messageToWrite)
{
Validate.IsNotNull("messageToWrite", messageToWrite);
// Log the JSON representation of the message
string logMessage = string.Format("Sending message of type[{0}] and method[{1}]",
messageToWrite.MessageType, messageToWrite.Method);
Logger.Write(TraceEventType.Verbose, logMessage);
string serializedMessage = messageToWrite.Serialize();
// TODO: Allow encoding to be passed in
byte[] messageBytes = Encoding.UTF8.GetBytes(serializedMessage);
string headers = ContentLength + messageBytes.Length + HeaderSeparator
+ ContentType + HeaderEnd;
byte[] headerBytes = Encoding.ASCII.GetBytes(headers);
// Make sure only one call is writing at a time. You might be thinking
// "Why not use a normal lock?" We use an AsyncLock here so that the
// message loop doesn't get blocked while waiting for I/O to complete.
using (await writeLock.LockAsync())
{
// Send the message
await outputStream.WriteAsync(headerBytes, 0, headerBytes.Length);
await outputStream.WriteAsync(messageBytes, 0, messageBytes.Length);
await outputStream.FlushAsync();
}
}
}
}