Files
Swarm/DysonNetwork.Pusher/Services/PusherServiceGrpc.cs
2025-08-24 18:05:42 +08:00

173 lines
6.2 KiB
C#

using DysonNetwork.Pusher.Connection;
using DysonNetwork.Pusher.Email;
using DysonNetwork.Pusher.Notification;
using DysonNetwork.Shared.Proto;
using DysonNetwork.Shared.Registry;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using System.Text.Json;
namespace DysonNetwork.Pusher.Services;
public class PusherServiceGrpc(
QueueService queueService,
WebSocketService websocket,
PushService pushService
) : PusherService.PusherServiceBase
{
public override async Task<Empty> SendEmail(SendEmailRequest request, ServerCallContext context)
{
await queueService.EnqueueEmail(
request.Email.ToName,
request.Email.ToAddress,
request.Email.Subject,
request.Email.Body
);
return new Empty();
}
public override Task<Empty> PushWebSocketPacket(PushWebSocketPacketRequest request, ServerCallContext context)
{
var packet = new Connection.WebSocketPacket
{
Type = request.Packet.Type,
Data = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(request.Packet.Data),
ErrorMessage = request.Packet.ErrorMessage
};
websocket.SendPacketToAccount(request.UserId, packet);
return Task.FromResult(new Empty());
}
public override Task<Empty> PushWebSocketPacketToUsers(PushWebSocketPacketToUsersRequest request,
ServerCallContext context)
{
var packet = new Connection.WebSocketPacket
{
Type = request.Packet.Type,
Data = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(request.Packet.Data),
ErrorMessage = request.Packet.ErrorMessage
};
foreach (var userId in request.UserIds)
{
websocket.SendPacketToAccount(userId, packet);
}
return Task.FromResult(new Empty());
}
public override Task<Empty> PushWebSocketPacketToDevice(PushWebSocketPacketToDeviceRequest request,
ServerCallContext context)
{
var packet = new Connection.WebSocketPacket
{
Type = request.Packet.Type,
Data = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(request.Packet.Data),
ErrorMessage = request.Packet.ErrorMessage
};
websocket.SendPacketToDevice(request.DeviceId, packet);
return Task.FromResult(new Empty());
}
public override Task<Empty> PushWebSocketPacketToDevices(PushWebSocketPacketToDevicesRequest request,
ServerCallContext context)
{
var packet = new Connection.WebSocketPacket
{
Type = request.Packet.Type,
Data = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(request.Packet.Data),
ErrorMessage = request.Packet.ErrorMessage
};
foreach (var deviceId in request.DeviceIds)
{
websocket.SendPacketToDevice(deviceId, packet);
}
return Task.FromResult(new Empty());
}
public override async Task<Empty> SendPushNotificationToUser(SendPushNotificationToUserRequest request,
ServerCallContext context)
{
var notification = new Notification.Notification
{
Topic = request.Notification.Topic,
Title = request.Notification.Title,
Subtitle = request.Notification.Subtitle,
Content = request.Notification.Body,
Meta = request.Notification.HasMeta
? GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(request.Notification.Meta) ?? []
: [],
AccountId = Guid.Parse(request.UserId),
};
if (request.Notification.ActionUri is not null)
notification.Meta["action_uri"] = request.Notification.ActionUri;
if (request.Notification.IsSavable)
await pushService.SaveNotification(notification);
await queueService.EnqueuePushNotification(
notification,
Guid.Parse(request.UserId),
request.Notification.IsSavable
);
return new Empty();
}
public override async Task<Empty> SendPushNotificationToUsers(SendPushNotificationToUsersRequest request,
ServerCallContext context)
{
var notification = new Notification.Notification
{
Topic = request.Notification.Topic,
Title = request.Notification.Title,
Subtitle = request.Notification.Subtitle,
Content = request.Notification.Body,
Meta = request.Notification.HasMeta
? GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(request.Notification.Meta) ?? []
: [],
};
if (request.Notification.ActionUri is not null)
notification.Meta["action_uri"] = request.Notification.ActionUri;
var userIds = request.UserIds.Select(Guid.Parse).ToList();
if (request.Notification.IsSavable)
await pushService.SaveNotification(notification, userIds);
var tasks = userIds
.Select(userId => queueService.EnqueuePushNotification(
notification,
userId,
request.Notification.IsSavable
));
await Task.WhenAll(tasks);
return new Empty();
}
public override async Task<Empty> UnsubscribePushNotifications(UnsubscribePushNotificationsRequest request,
ServerCallContext context)
{
await pushService.UnsubscribeDevice(request.DeviceId);
return new Empty();
}
public override Task<GetWebsocketConnectionStatusResponse> GetWebsocketConnectionStatus(
GetWebsocketConnectionStatusRequest request, ServerCallContext context)
{
var isConnected = request.IdCase switch
{
GetWebsocketConnectionStatusRequest.IdOneofCase.DeviceId =>
websocket.GetDeviceIsConnected(request.DeviceId),
GetWebsocketConnectionStatusRequest.IdOneofCase.UserId => websocket.GetAccountIsConnected(request.UserId),
_ => false
};
return Task.FromResult(new GetWebsocketConnectionStatusResponse { IsConnected = isConnected });
}
}