Untitled

 avatar
unknown
plain_text
2 years ago
2.7 kB
4
Indexable
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Utils;
using Chat;

namespace ChatServer
{
    public class ChatService : ChatRoom.ChatRoomBase
    {
        private readonly ConcurrentDictionary<string, IServerStreamWriter<ChatMessage>> _connectedClients = 
            new ConcurrentDictionary<string, IServerStreamWriter<ChatMessage>>();

        public async Task BroadcastMessageAsync(ChatMessage message)
        {
            foreach (var client in _connectedClients.Values)
            {
                await client.WriteAsync(message);
            }
        }

        public override async Task JoinChat(ChatUser user, IServerStreamWriter<ChatMessage> responseStream, ServerCallContext context)
        {
            _connectedClients[user.Name] = responseStream;
            await BroadcastMessageAsync(new ChatMessage { User = user, Text = "joined the chat." });

            try
            {
                await Task.Delay(-1, context.CancellationToken);
            }
            catch (TaskCanceledException)
            {
                _connectedClients.TryRemove(user.Name, out _);
                await BroadcastMessageAsync(new ChatMessage { User = user, Text = "left the chat." });
            }
        }

        public async Task SendMessageAsync(ChatUser sender, string recipientName, string messageText)
        {
            if (_connectedClients.TryGetValue(recipientName, out var recipient))
            {
                await recipient.WriteAsync(new ChatMessage { User = sender, Text = messageText });
            }
            else
            {
                Console.WriteLine($"User '{recipientName}' not found.");
            }
        }

        public override Task<Empty> SendChatMessage(ChatMessage message, ServerCallContext context)
        {
            var recipientName = message.Text.Substring(1, message.Text.IndexOf(' ') - 1);
            var messageText = message.Text.Substring(recipientName.Length + 2);

            SendMessageAsync(message.User, recipientName, messageText).Wait(context.CancellationToken);
            return Task.FromResult(new Empty());
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var server = new Server
            {
                Services = { ChatRoom.BindService(new ChatService()) },
                Ports = { new ServerPort("localhost", 50051, ServerCredentials.Insecure) }
            };
            server.Start();

            Console.WriteLine("Chat server listening on port 50051.");

            await server.ShutdownAsync();
        }
    }
}
Editor is loading...