Skip to content

Commit

Permalink
NuGet v6.3.0, server-sent events support, refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jchristn committed Dec 13, 2024
1 parent 6c751d9 commit 999dbc3
Show file tree
Hide file tree
Showing 78 changed files with 1,506 additions and 1,190 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Current Version

v6.3.x

- Minor change to chunked transfer, i.e. `SendChunk` now accepts `isFinal` as a `Boolean` property
- Added support for server-sent events, included `Test.ServerSentEvents` project
- Minor internal refactor

v6.2.x

- Support for specifying exception handler for static, content, parameter, and dynamic routes (thank you @nomadeon)
Expand Down
42 changes: 38 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ Special thanks to @DamienDennehy for allowing us the use of the ```Watson.Core``

This project is part of the [.NET Foundation](http://www.dotnetfoundation.org/projects) along with other projects like [the .NET Runtime](https://github.com/dotnet/runtime/).

## New in v6.2.x
## New in v6.3.x

- Support for specifying exception handler for static, content, parameter, and dynamic routes (thank you @nomadeon)
- Minor change to chunked transfer, i.e. `SendChunk` now accepts `isFinal` as a `Boolean` property
- Added support for server-sent events, included `Test.ServerSentEvents` project
- Minor internal refactor

## Special Thanks

Expand Down Expand Up @@ -232,13 +234,16 @@ static async Task DownloadChunkedFile(HttpContextBase ctx)
while (true)
{
int bytesRead = await fs.ReadAsync(buffer, 0, buffer.Length);
byte[] data = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, bytesRead, data, 0); // only copy the read data
if (bytesRead > 0)
{
await ctx.Response.SendChunk(buffer, bytesRead);
await ctx.Response.SendChunk(data, false);
}
else
{
await ctx.Response.SendFinalChunk(null, 0);
await ctx.Response.SendChunk(Array.Empty<byte>(), true);
break;
}
}
Expand All @@ -248,6 +253,35 @@ static async Task DownloadChunkedFile(HttpContextBase ctx)
}
```

## Server-Sent Events

Watson supports sending server-sent events. Refer to `Test.ServerSentEvents` for a sample implementation. The `SendEvent` method handles prepending `data: ` and the following `\n\n` to your message.

### Sending Events

```csharp
static async Task SendEvents(HttpContextBase ctx)
{
ctx.Response.StatusCode = 200;
ctx.Response.ServerSentEvents = true;

while (true)
{
string data = GetNextEvent(); // your implementation
if (!String.IsNullOrEmpty(data))
{
await ctx.Response.SendEvent(data);
}
else
{
break;
}
}

return;
}
```

## HostBuilder

`HostBuilder` helps you set up your server much more easily by introducing a chain of settings and routes instead of using the server class directly. Special thanks to @sapurtcomputer30 for producing this fine feature!
Expand Down
24 changes: 12 additions & 12 deletions src/Test.Authentication/Program.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using RestWrapper;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

namespace Test.Authentication
namespace Test.Authentication
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using RestWrapper;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

static class Program
{
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
Expand Down
52 changes: 27 additions & 25 deletions src/Test.ChunkServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

namespace Test
namespace Test
{
static class Program
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

public static class Program
{
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

static bool _UsingLite = false;
static string _Hostname = "localhost";
static int _Port = 8080;
static WebserverSettings _Settings = null;
static WebserverBase _Server = null;

static void Main(string[] args)
static async Task Main(string[] args)
{
if (args != null && args.Length > 0)
{
Expand Down Expand Up @@ -117,13 +119,13 @@ static async Task DefaultRoute(HttpContextBase ctx)

if (bytesRead == buffer.Length)
{
await ctx.Response.SendChunk(buffer);
await ctx.Response.SendChunk(buffer, false);
}
else
{
byte[] temp = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, temp, 0, bytesRead);
await ctx.Response.SendChunk(temp);
await ctx.Response.SendChunk(temp, false);
}
}
else
Expand All @@ -132,13 +134,13 @@ static async Task DefaultRoute(HttpContextBase ctx)

if (bytesRead == buffer.Length)
{
await ctx.Response.SendFinalChunk(buffer);
await ctx.Response.SendChunk(buffer, true);
}
else
{
byte[] temp = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, temp, 0, bytesRead);
await ctx.Response.SendFinalChunk(temp);
await ctx.Response.SendChunk(temp, true);
}
}

Expand Down Expand Up @@ -183,13 +185,13 @@ static async Task DefaultRoute(HttpContextBase ctx)

if (bytesRead == buffer.Length)
{
await ctx.Response.SendChunk(buffer);
await ctx.Response.SendChunk(buffer, false);
}
else
{
byte[] temp = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, temp, 0, bytesRead);
await ctx.Response.SendChunk(temp);
await ctx.Response.SendChunk(temp, false);
}
}
else
Expand All @@ -198,16 +200,14 @@ static async Task DefaultRoute(HttpContextBase ctx)

if (bytesRead == buffer.Length)
{
await ctx.Response.SendFinalChunk(buffer);
await ctx.Response.SendChunk(buffer, true);
}
else
{
byte[] temp = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, temp, 0, bytesRead);
await ctx.Response.SendFinalChunk(temp);
await ctx.Response.SendChunk(temp, true);
}

await ctx.Response.SendFinalChunk(buffer);
}

bytesSent += bytesRead;
Expand All @@ -230,6 +230,8 @@ static async Task DefaultRoute(HttpContextBase ctx)
{
Console.WriteLine(e.ToString());
}
}
}

#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
}
}
3 changes: 2 additions & 1 deletion src/Test.ChunkServer/Test.ChunkServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net462;net48;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net48;net6.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand All @@ -16,6 +16,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WatsonWebserver.Core\WatsonWebserver.Core.csproj" />
<ProjectReference Include="..\WatsonWebserver.Lite\WatsonWebserver.Lite.csproj" />
<ProjectReference Include="..\WatsonWebserver\WatsonWebserver.csproj" />
</ItemGroup>
Expand Down
22 changes: 11 additions & 11 deletions src/Test.DataReader/Program.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GetSomeInput;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

namespace Test
namespace Test
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GetSomeInput;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

static class Program
{
static bool _UsingLite = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Test.DataReader/Test.DataReader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net462;net48;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net48;net6.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Test.Default/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using GetSomeInput;
namespace Test
namespace Test
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using GetSomeInput;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;
Expand Down
2 changes: 1 addition & 1 deletion src/Test.Default/Test.Default.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net462;net48;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net48;net6.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Test.Docker/Test.Docker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net462;net48;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net48;net6.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
24 changes: 12 additions & 12 deletions src/Test.HostBuilder/Program.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using RestWrapper;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

namespace Test.HostBuilder
namespace Test.HostBuilder
{
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using RestWrapper;
using WatsonWebserver;
using WatsonWebserver.Core;
using WatsonWebserver.Lite;

public static class Program
{
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
Expand All @@ -20,7 +20,7 @@ public static class Program
static WebserverSettings _Settings = null;
static WebserverBase _Server = null;

public static void Main(string[] args)
public static async Task Main(string[] args)
{
if (args != null && args.Length > 0)
{
Expand Down Expand Up @@ -156,7 +156,7 @@ public static void Main(string[] args)

using (RestRequest req = new RestRequest(url))
{
using (RestResponse resp = req.Send())
using (RestResponse resp = await req.SendAsync())
{
Console.WriteLine("Received response: " + resp.StatusCode);
Task.Delay(1000).Wait();
Expand Down
5 changes: 3 additions & 2 deletions src/Test.HostBuilder/Test.HostBuilder.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net462;net48;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net48;net6.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="RestWrapper" Version="3.0.14" />
<PackageReference Include="RestWrapper" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WatsonWebserver.Core\WatsonWebserver.Core.csproj" />
<ProjectReference Include="..\WatsonWebserver.Lite\WatsonWebserver.Lite.csproj" />
<ProjectReference Include="..\WatsonWebserver\WatsonWebserver.csproj" />
</ItemGroup>
Expand Down
Loading

0 comments on commit 999dbc3

Please sign in to comment.