Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch Websockets #1

Merged
merged 3 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .github/workflows/docker-deploy.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: Build and Push Docker Image

on:
pull_request:
branches: [ master ]
push:
branches: [ master ]

Expand All @@ -14,10 +12,24 @@ jobs:
- name: Check out the repository
uses: actions/checkout@v2

- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.x'

- name: Log in to Docker Hub
run: |
docker login guildwarspartysearch.azurecr.io --username "${{ secrets.DOCKERHUB_USERNAME }}" --password "${{ secrets.DOCKERHUB_PASSWORD }}"

- name: Replace Config Placeholders
shell: pwsh
run: |
cd GuildWarsPartySearch
$content = Get-Content Config.json
$updatedContent = $content -replace "[API_KEY_PLACEHOLDER]", "${{ secrets.APIKEY }}"
Set-Content -Path Config.json -Value $updatedContent
Write-Host "Placeholder replaced successfully in Config.json"

- name: Build and push Docker image
run: |
cd GuildWarsPartySearch
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Run tests

on:
pull_request:
branches: [ master ]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Check out the repository
uses: actions/checkout@v2

- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.x'

- name: Run tests
shell: pwsh
run: |
dotnet test .\GuildWarsPartySearch.Tests\
1 change: 1 addition & 0 deletions GuildWarsPartySearch.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipelines", "Pipelines", "{6C63473D-A6D9-400D-94AD-2E4DBA48B8B8}"
ProjectSection(SolutionItems) = preProject
.github\workflows\docker-deploy.yaml = .github\workflows\docker-deploy.yaml
.github\workflows\test.yaml = .github\workflows\test.yaml
EndProjectSection
EndProject
Global
Expand Down
5 changes: 5 additions & 0 deletions GuildWarsPartySearch/Config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ServerOptions": {
"ApiKey": "[API_KEY_PLACEHOLDER]"
}
}
18 changes: 18 additions & 0 deletions GuildWarsPartySearch/Converters/NoneWebsocketMessageConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using GuildWarsPartySearch.Server.Models.Endpoints;
using MTSC.Common.WebSockets;
using MTSC.Common.WebSockets.RoutingModules;

namespace GuildWarsPartySearch.Server.Converters;

public sealed class NoneWebsocketMessageConverter : IWebsocketMessageConverter<None>
{
public None ConvertFromWebsocketMessage(WebsocketMessage websocketMessage)
{
return new None();
}

public WebsocketMessage ConvertToWebsocketMessage(None message)
{
return new WebsocketMessage { FIN = true };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using GuildWarsPartySearch.Server.Models.Endpoints;
using MTSC.Common.WebSockets;
using MTSC.Common.WebSockets.RoutingModules;
using Newtonsoft.Json;
using System.Text;

namespace GuildWarsPartySearch.Server.Converters;

public sealed class PostPartyRequestWebsocketMessageConverter : IWebsocketMessageConverter<PostPartySearchRequest>
{
public PostPartyRequestWebsocketMessageConverter()
{
}

public WebsocketMessage ConvertToWebsocketMessage(PostPartySearchRequest message)
{
var serializedData = JsonConvert.SerializeObject(message);
var bytes = Encoding.UTF8.GetBytes(serializedData);
return new WebsocketMessage
{
Data = bytes,
Opcode = WebsocketMessage.Opcodes.Text
};
}

PostPartySearchRequest IWebsocketMessageConverter<PostPartySearchRequest>.ConvertFromWebsocketMessage(WebsocketMessage websocketMessage)
{
var bytes = websocketMessage.Data;
var serializedData = Encoding.UTF8.GetString(bytes);
try
{
return JsonConvert.DeserializeObject<PostPartySearchRequest>(serializedData)!;
}
catch(Exception ex)
{
return default!;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using GuildWarsPartySearch.Server.Models.Endpoints;
using MTSC.Common.WebSockets;
using MTSC.Common.WebSockets.RoutingModules;
using Newtonsoft.Json;
using System.Text;

namespace GuildWarsPartySearch.Server.Converters;

public sealed class PostPartyResponseWebsocketMessageConverter : IWebsocketMessageConverter<PostPartySearchResponse>
{
public WebsocketMessage ConvertToWebsocketMessage(PostPartySearchResponse message)
{
var serializedData = JsonConvert.SerializeObject(message);
var bytes = Encoding.UTF8.GetBytes(serializedData);
return new WebsocketMessage
{
Data = bytes,
Opcode = WebsocketMessage.Opcodes.Text,
FIN = true
};
}

PostPartySearchResponse IWebsocketMessageConverter<PostPartySearchResponse>.ConvertFromWebsocketMessage(WebsocketMessage websocketMessage)
{
var bytes = websocketMessage.Data;
var serializedData = Encoding.UTF8.GetString(bytes);
return JsonConvert.DeserializeObject<PostPartySearchResponse>(serializedData)!;
}
}
117 changes: 0 additions & 117 deletions GuildWarsPartySearch/Endpoints/GetPartySearch.cs

This file was deleted.

61 changes: 61 additions & 0 deletions GuildWarsPartySearch/Endpoints/LiveFeed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using GuildWarsPartySearch.Server.Models.Endpoints;
using GuildWarsPartySearch.Server.Services.Feed;
using GuildWarsPartySearch.Server.Services.PartySearch;
using Microsoft.Extensions.Logging;
using MTSC.Common.WebSockets;
using MTSC.Common.WebSockets.RoutingModules;
using Newtonsoft.Json;
using System.Core.Extensions;
using System.Extensions;
using System.Text;

namespace GuildWarsPartySearch.Server.Endpoints;

public sealed class LiveFeed : WebsocketRouteBase<None>
{
private readonly IPartySearchService partySearchService;
private readonly ILiveFeedService liveFeedService;
private readonly ILogger<LiveFeed> logger;

public LiveFeed(
IPartySearchService partySearchService,
ILiveFeedService liveFeedService,
ILogger<LiveFeed> logger)
{
this.partySearchService = partySearchService.ThrowIfNull();
this.liveFeedService = liveFeedService.ThrowIfNull();
this.logger = logger.ThrowIfNull();
}

public override void ConnectionClosed()
{
var scopedLogger = this.logger.CreateScopedLogger(nameof(this.ConnectionInitialized), this.ClientData.Socket.RemoteEndPoint?.ToString() ?? string.Empty);
scopedLogger.LogInformation("Client connected");
this.liveFeedService.RemoveClient(this.ClientData);
}

public override async void ConnectionInitialized()
{
var scopedLogger = this.logger.CreateScopedLogger(nameof(this.ConnectionInitialized), this.ClientData.Socket.RemoteEndPoint?.ToString() ?? string.Empty);
scopedLogger.LogInformation("Client connected");
this.liveFeedService.AddClient(this.ClientData);
scopedLogger.LogInformation("Sending all party searches");
var updates = await this.partySearchService.GetAllPartySearches();
var serialized = JsonConvert.SerializeObject(updates);
var payload = Encoding.UTF8.GetBytes(serialized);
this.SendMessage(new WebsocketMessage
{
Data = payload,
FIN = true,
Opcode = WebsocketMessage.Opcodes.Text
});
}

public override void HandleReceivedMessage(None message)
{
}

public override void Tick()
{
}
}
Loading
Loading