UIMessage communication. Single instancing for server and re-connection mechanism on suspension.

This commit is contained in:
Burak Kaan Köse
2024-07-17 22:36:10 +02:00
parent ad1c7e1fd3
commit 329eae3a25
87 changed files with 412 additions and 321 deletions

View File

@@ -1,12 +1,21 @@
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.AppService;
using Windows.Foundation.Collections;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Interfaces;
using Wino.Messaging;
using Wino.Messaging.Enums;
using Wino.Messaging.Server;
namespace Wino.Server
{
public class ServerContext
{
private static object connectionLock = new object();
private AppServiceConnection connection = null;
public ServerContext()
@@ -14,15 +23,33 @@ namespace Wino.Server
InitializeAppServiceConnection();
}
private string GetAppPackagFamilyName()
{
// If running as a standalone app, Package will throw exception.
// Return hardcoded value for debugging purposes.
// Connection will not be available in this case.
try
{
return Package.Current.Id.FamilyName;
}
catch (Exception)
{
return "Debug.Wino.Server.FamilyName";
}
}
/// <summary>
/// Open connection to UWP app service
/// </summary>
public async void InitializeAppServiceConnection()
{
if (connection != null) DisposeConnection();
connection = new AppServiceConnection
{
AppServiceName = "WinoInteropService",
PackageFamilyName = Package.Current.Id.FamilyName
PackageFamilyName = GetAppPackagFamilyName()
};
connection.RequestReceived += OnWinRTMessageReceived;
@@ -33,13 +60,33 @@ namespace Wino.Server
if (status != AppServiceConnectionStatus.Success)
{
// TODO: Handle connection error
DisposeConnection();
}
}
public async void SendMessage()
public Task SendTestMessageAsync()
{
var set = new ValueSet();
set.Add("Hello", "World");
var message = new MailAddedMessage(new MailCopy());
return SendMessageAsync(MessageType.UIMessage, message);
}
private async Task SendMessageAsync(MessageType messageType, object message)
{
if (connection == null) return;
if (message is not IServerMessage serverMessage)
throw new ArgumentException("Server message must be a type of IServerMessage");
string json = JsonSerializer.Serialize(message);
var set = new ValueSet
{
{ MessageConstants.MessageTypeKey, (int)messageType },
{ MessageConstants.MessageDataKey, json },
{ MessageConstants.MessageDataTypeKey, message.GetType().Name }
};
await connection.SendMessageAsync(set);
}
@@ -47,12 +94,30 @@ namespace Wino.Server
{
// TODO: Handle connection closed.
// UWP app might've been terminated.
// UWP app might've been terminated or suspended.
// At this point, we must keep active synchronizations going, but connection is lost.
// As long as this process is alive, database will be kept updated, but no messages will be sent.
DisposeConnection();
}
private void OnWinRTMessageReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
// TODO: Handle incoming messages from UWP/WINUI Application.
}
private void DisposeConnection()
{
lock (connectionLock)
{
if (connection == null) return;
connection.RequestReceived -= OnWinRTMessageReceived;
connection.ServiceClosed -= OnConnectionClosed;
connection.Dispose();
connection = null;
}
}
}
}