첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestSolution.zip
0.01MB

[TestLibrary 프로젝트]

▶ ConnectRequest.cs

namespace TestLibrary
{
    /// <summary>
    /// 연결 요청
    /// </summary>
    public class ConnectRequest
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 사용자명 - UserName

        /// <summary>
        /// 사용자명
        /// </summary>
        public string UserName { get; set; }

        #endregion
    }
}

 

728x90

 

▶ ConnectResponse.cs

namespace TestLibrary
{
    /// <summary>
    /// 연결 응답
    /// </summary>
    public class ConnectResponse
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 메시지 - Message

        /// <summary>
        /// 메시지
        /// </summary>
        public string Message { get; set; }

        #endregion
    }
}

 

300x250

 

▶ NickNameRequest.cs

namespace TestLibrary
{
    /// <summary>
    /// 닉네임 요청
    /// </summary>
    public class NickNameRequest
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 사용자명 - UserName

        /// <summary>
        /// 사용자명
        /// </summary>
        public string UserName { get; set; }

        #endregion
        #region 신규 사용자명 - NewUserName

        /// <summary>
        /// 신규 사용자명
        /// </summary>
        public string NewUserName { get; set; }

        #endregion
    }
}

 

반응형

 

▶ NickNameResponse.cs

namespace TestLibrary
{
    /// <summary>
    /// 닉네임 응답
    /// </summary>
    public class NickNameResponse
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 사용자명 - UserName

        /// <summary>
        /// 사용자명
        /// </summary>
        public string UserName { get; set; }

        #endregion
        #region 신규 사용자명 - NewUserName

        /// <summary>
        /// 신규 사용자명
        /// </summary>
        public string NewUserName { get; set; }

        #endregion
    }
}

 

▶ SayRequest.cs

namespace TestLibrary
{
    /// <summary>
    /// 말하기 요청
    /// </summary>
    public class SayRequest
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 사용자명 - UserName

        /// <summary>
        /// 사용자명
        /// </summary>
        public string UserName { get; set; }

        #endregion
        #region 메시지 - Message

        /// <summary>
        /// 메시지
        /// </summary>
        public string Message { get; set; }

        #endregion
    }
}

 

▶ SayResponse.cs

namespace TestLibrary
{
    /// <summary>
    /// 말하기 응답
    /// </summary>
    public class SayResponse
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 사용자명 - UserName

        /// <summary>
        /// 사용자명
        /// </summary>
        public string UserName { get; set; }

        #endregion
        #region 메시지 - Message

        /// <summary>
        /// 메시지
        /// </summary>
        public string Message { get; set; }

        #endregion
    }
}

 

[TestServer 프로젝트]

▶ ChatServerActor.cs

using System.Collections.Generic;

using Akka.Actor;

using TestLibrary;

namespace TestServer
{
    /// <summary>
    /// 채팅 서버 액터
    /// </summary>
    public class ChatServerActor : ReceiveActor, ILogReceive
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 액터 참조 해시 세트
        /// </summary>
        private readonly HashSet<IActorRef> actorRefHashSet = new HashSet<IActorRef>();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ChatServerActor()

        /// <summary>
        /// 생성자
        /// </summary>
        public ChatServerActor()
        {
            Receive<ConnectRequest>
            (
                connectRequest =>
                {
                    this.actorRefHashSet.Add(Sender);

                    Sender.Tell
                    (
                        new ConnectResponse
                        {
                            Message = "Hello and welcome to Akka.NET chat example",
                        },
                        Self
                    );
                }
            );

            Receive<NickNameRequest>
            (
                nickNameRequest =>
                {
                    NickNameResponse nickNameResponse = new NickNameResponse
                    {
                        UserName    = nickNameRequest.UserName,
                        NewUserName = nickNameRequest.NewUserName,
                    };

                    foreach(IActorRef actorRef in this.actorRefHashSet)
                    {
                        actorRef.Tell(nickNameResponse, Self);
                    }
                }
            );

            Receive<SayRequest>
            (
                sayRequest =>
                {
                    SayResponse sayResponse = new SayResponse
                    {
                        UserName = sayRequest.UserName,
                        Message  = sayRequest.Message,
                    };

                    foreach(IActorRef actorRef in this.actorRefHashSet)
                    {
                        actorRef.Tell(sayResponse, Self);
                    }
                }
            );
        }

        #endregion
    }
}

 

▶ Program.cs

using System;

using Akka.Actor;
using Akka.Configuration;

namespace TestServer
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            string hocon = @"
akka
{  
    actor
    {
        provider = remote
    }
    remote
    {
        dot-netty.tcp
        {
            port            = 9999
            hostname        = 0.0.0.0
            public-hostname = localhost
        }
    }
}
";

            Config config = ConfigurationFactory.ParseString(hocon);

            using(ActorSystem actorSystem = ActorSystem.Create("TestServer", config))
            {
                actorSystem.ActorOf(Props.Create(() => new ChatServerActor()), "ChatServer");

                Console.ReadLine();
            }
        }

        #endregion
    }
}

 

[TestClient 프로젝트]

▶ ChatClientActor.cs

using System;

using Akka.Actor;

using TestLibrary;

namespace TestClient
{
    /// <summary>
    /// 채팅 클라이언트 액터
    /// </summary>
    public class ChatClientActor : ReceiveActor, ILogReceive
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 액터 선택
        /// </summary>
        private readonly ActorSelection actorSelection = Context.ActorSelection("akka.tcp://TestServer@localhost:9999/user/ChatServer");

        /// <summary>
        /// 닉네임
        /// </summary>
        private string nickName = "Roggan";

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ChatClientActor()

        /// <summary>
        /// 생성자
        /// </summary>
        public ChatClientActor()
        {
            Receive<ConnectRequest>
            (
                connectRequest =>
                {
                    Console.WriteLine("Connecting....");

                    this.actorSelection.Tell(connectRequest);
                }
            );

            Receive<ConnectResponse>
            (
                connectResponse =>
                {
                    Console.WriteLine("Connected!");

                    Console.WriteLine(connectResponse.Message);
                }
            );

            Receive<NickNameRequest>
            (
                nickNameRequest =>
                {
                    nickNameRequest.UserName = this.nickName;

                    Console.WriteLine($"Changing nick to {nickNameRequest.NewUserName}");

                    this.nickName = nickNameRequest.NewUserName;

                    this.actorSelection.Tell(nickNameRequest);
                }
            );

            Receive<NickNameResponse>
            (
                nickNameRequest =>
                {
                    Console.WriteLine($"{nickNameRequest.UserName} is now known as {nickNameRequest.NewUserName}");
                }
            );

            Receive<SayRequest>
            (
                sayRequest =>
                {
                    sayRequest.UserName = this.nickName;

                    this.actorSelection.Tell(sayRequest);
                }
            );

            Receive<SayResponse>
            (
                sayResponse =>
                {
                    Console.WriteLine($"{sayResponse.UserName} : {sayResponse.Message}");
                }
            );
        }

        #endregion
    }
}

 

▶ Program.cs

using System;
using System.Linq;

using Akka.Actor;
using Akka.Configuration;

using TestLibrary;

namespace TestClient
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            string hocon = @"
akka
{  
    actor
    {
        provider = remote
    }
    remote
    {
        dot-netty.tcp
        {
            port     = 0
            hostname = localhost
        }
    }
}
";

            Config config = ConfigurationFactory.ParseString(hocon);

            using(ActorSystem actorSystem = ActorSystem.Create("TestClient", config))
            {
                IActorRef actorRef = actorSystem.ActorOf(Props.Create<ChatClientActor>());

                actorRef.Tell(new ConnectRequest() { UserName = "Roggan", });

                while(true)
                {
                    string input = Console.ReadLine();

                    if(input.StartsWith("/"))
                    {
                        string[] partArray = input.Split(' ');
                        string   command   = partArray[0].ToLowerInvariant();
                        string   rest      = string.Join(" ", partArray.Skip(1));

                        if(command == "/nick")
                        {
                            actorRef.Tell(new NickNameRequest { NewUserName = rest });
                        }

                        if(command == "/exit")
                        {
                            Console.WriteLine("exiting");

                            break;
                        }
                    }
                    else
                    {
                        actorRef.Tell(new SayRequest() { Message = input });
                    }
                }

                actorSystem.Terminate().Wait();
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)

'C# > Akka.NET' 카테고리의 다른 글

[C#/AKKA.NET] 누겟 설치 : Akka.Remote  (0) 2021.09.10
[C#/AKKA.NET] 누겟 설치 : Akka  (0) 2021.09.10
Posted by icodebroker

댓글을 달아 주세요