Permalink
Browse files

Changed IResponse Write and End methods to take ArraySegment<byte> in…

…stead of string

- Updated the hosts
- Added extension methods to Write and End that take a string.
  • Loading branch information...
davidfowl committed Jun 4, 2012
1 parent 720a64b commit f521fd2e6af967ce3603244bd7ed8606313f48a5
@@ -57,12 +57,12 @@ public string ContentType
}
}
- public Task WriteAsync(string data)
+ public Task WriteAsync(ArraySegment<byte> data)
{
return WriteAsync(data, disableBuffering: true);
}
- private Task WriteAsync(string data, bool disableBuffering)
+ private Task WriteAsync(ArraySegment<byte> data, bool disableBuffering)
{
if (disableBuffering)
{
@@ -73,8 +73,8 @@ private Task WriteAsync(string data, bool disableBuffering)
{
return TaskAsyncHelper.Empty;
}
-
- _context.Response.Write(data);
+
+ _context.Response.OutputStream.Write(data.Array, data.Offset, data.Count);
return Task.Factory.FromAsync((cb, state) => _context.Response.BeginFlush(cb, state), ar => _context.Response.EndFlush(ar), null);
#else
@@ -84,7 +84,7 @@ private Task WriteAsync(string data, bool disableBuffering)
{
if (IsClientConnected)
{
- response.Write(value);
+ response.OutputStream.Write(value.Array, value.Offset, value.Count);
response.Flush();
}
@@ -95,7 +95,7 @@ private Task WriteAsync(string data, bool disableBuffering)
#endif
}
- public Task EndAsync(string data)
+ public Task EndAsync(ArraySegment<byte> data)
{
return WriteAsync(data, disableBuffering: false);
}
@@ -10,7 +10,7 @@ namespace SignalR.Hosting.Memory
{
public class Response : IClientResponse, IResponse
{
- private string _nonStreamingData;
+ private ArraySegment<byte> _nonStreamingData;
private readonly CancellationToken _clientToken;
private readonly FollowStream _responseStream;
private bool _ended;
@@ -23,7 +23,12 @@ public Response(CancellationToken clientToken, Action startSending)
public string ReadAsString()
{
- return _nonStreamingData;
+ if (_nonStreamingData.Array == null)
+ {
+ return null;
+ }
+
+ return Encoding.UTF8.GetString(_nonStreamingData.Array, _nonStreamingData.Offset, _nonStreamingData.Count);
}
public Stream GetResponseStream()
@@ -50,17 +55,17 @@ public string ContentType
set;
}
- public Task WriteAsync(string data)
+ public Task WriteAsync(ArraySegment<byte> data)
{
if (IsClientConnected)
{
- _responseStream.Write(data);
+ _responseStream.Write(data.Array, data.Offset, data.Count);
}
return TaskAsyncHelper.Empty;
}
- public Task EndAsync(string data)
+ public Task EndAsync(ArraySegment<byte> data)
{
_nonStreamingData = data;
_ended = true;
@@ -35,12 +35,12 @@ public bool IsClientConnected
private set;
}
- public Task WriteAsync(string data)
+ public Task WriteAsync(ArraySegment<byte> data)
{
return WriteAsync(data, end: false);
}
- public Task EndAsync(string data)
+ public Task EndAsync(ArraySegment<byte> data)
{
return WriteAsync(data, end: true);
}
@@ -50,7 +50,7 @@ public Task End()
return EnsureResponseStarted().Then(cb => cb(), _responseCompete);
}
- private Task WriteAsync(string data, bool end)
+ private Task WriteAsync(ArraySegment<byte> data, bool end)
{
return EnsureResponseStarted()
.Then((d, e) => DoWrite(d, e), data, end);
@@ -95,7 +95,7 @@ private void StopSending()
IsClientConnected = false;
}
- private Task DoWrite(string data, bool end)
+ private Task DoWrite(ArraySegment<byte> data, bool end)
{
if (!IsClientConnected)
{
@@ -106,18 +106,17 @@ private Task DoWrite(string data, bool end)
try
{
- var value = new ArraySegment<byte>(Encoding.UTF8.GetBytes(data));
if (end)
{
// Write and send the response immediately
- _responseNext(value, null);
+ _responseNext(data, null);
_responseCompete();
tcs.SetResult(null);
}
else
{
- if (!_responseNext(value, () => tcs.SetResult(null)))
+ if (!_responseNext(data, () => tcs.SetResult(null)))
{
tcs.SetResult(null);
}
@@ -42,7 +42,7 @@ public bool IsClientConnected
}
}
- public Task WriteAsync(string data)
+ public Task WriteAsync(ArraySegment<byte> data)
{
if (Interlocked.Exchange(ref _writeInitialized, 1) == 0)
{
@@ -53,7 +53,7 @@ public Task WriteAsync(string data)
.Catch(ex => _ended = true);
}
- public Task EndAsync(string data)
+ public Task EndAsync(ArraySegment<byte> data)
{
return DoWrite(data).Then(response =>
{
@@ -65,7 +65,7 @@ public Task EndAsync(string data)
_httpListenerResponse);
}
- private Task DoWrite(string data)
+ private Task DoWrite(ArraySegment<byte> data)
{
if (!IsClientConnected)
{
@@ -21,14 +21,15 @@ public static Task ServerError(this HttpListenerResponse response, Exception exc
public static Task WriteAsync(this HttpListenerResponse response, string value)
{
- return WriteAsync(response, Encoding.UTF8.GetBytes(value));
+ var bytes = Encoding.UTF8.GetBytes(value);
+ return WriteAsync(response, new ArraySegment<byte>(bytes));
}
- public static Task WriteAsync(this HttpListenerResponse response, byte[] buffer)
+ public static Task WriteAsync(this HttpListenerResponse response, ArraySegment<byte> buffer)
{
try
{
- return Task.Factory.FromAsync((cb, state) => response.OutputStream.BeginWrite(buffer, 0, buffer.Length, cb, state),
+ return Task.Factory.FromAsync((cb, state) => response.OutputStream.BeginWrite(buffer.Array, buffer.Offset, buffer.Count, cb, state),
ar => response.OutputStream.EndWrite(ar),
null);
}
@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
namespace SignalR
{
@@ -20,15 +21,15 @@ public interface IResponse
/// <summary>
/// Writes unbuffered data that is immediately available to the client connection. (e.g. chunked over http).
/// </summary>
- /// <param name="data"></param>
+ /// <param name="data">The data to write to the connection.</param>
/// <returns>A task that represents when the write operation is complete.</returns>
- Task WriteAsync(string data);
+ Task WriteAsync(ArraySegment<byte> data);
/// <summary>
/// Closes the connection to a client with optional data.
/// </summary>
- /// <param name="data"></param>
+ /// <param name="data">The data to write to the connection.</param>
/// <returns>A task that represents when the connection is closed.</returns>
- Task EndAsync(string data);
+ Task EndAsync(ArraySegment<byte> data);
}
}
@@ -0,0 +1,36 @@
+using System;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SignalR
+{
+ /// <summary>
+ /// Extension methods for <see cref="IResponse"/>.
+ /// </summary>
+ public static class ResponseExtensions
+ {
+ /// <summary>
+ /// Writes unbuffered data that is immediately available to the client connection. (e.g. chunked over http).
+ /// </summary>
+ /// <param name="response">The <see cref="IResponse"/>.</param>
+ /// <param name="data">The data to write to the connection.</param>
+ /// <returns>A task that represents when the write operation is complete.</returns>
+ public static Task WriteAsync(this IResponse response, string data)
+ {
+ var bytes = Encoding.UTF8.GetBytes(data);
+ return response.WriteAsync(new ArraySegment<byte>(bytes));
+ }
+
+ /// <summary>
+ /// Closes the connection to a client with optional data.
+ /// </summary>
+ /// <param name="response">The <see cref="IResponse"/>.</param>
+ /// <param name="data">The data to write to the connection.</param>
+ /// <returns>A task that represents when the connection is closed.</returns>
+ public static Task EndAsync(this IResponse response, string data)
+ {
+ var bytes = Encoding.UTF8.GetBytes(data);
+ return response.EndAsync(new ArraySegment<byte>(bytes));
+ }
+ }
+}
View
@@ -56,6 +56,7 @@
<Compile Include="Hosting\IResponse.cs" />
<Compile Include="CommandType.cs" />
<Compile Include="Hosting\IWebSocket.cs" />
+ <Compile Include="Hosting\ResponseExtensions.cs" />
<Compile Include="Hubs\HubContext.cs" />
<Compile Include="Hubs\HubRequest.cs" />
<Compile Include="Hubs\HubRequestParser.cs" />

0 comments on commit f521fd2

Please sign in to comment.