제로 기반 서버 응용: 채팅방 ChatApp
수많은 온라인 게임, 모바일 게임에서 프로그램만 연결할 수 있다면 거의 모든 게임에서 단체 채팅, 1:1 대화, 표정 이모티콘 등 자주 사용하는 채팅 응용 범위 내 통신 기능을 제공할 수 있습니다. 이에, 이번 파트에서는 저희만의 Photon Server 내 채팅 서버 응응프로그램 구축 방법에 대해 알아보겠습니다. 구축에 소요되는 시간은 단 10분에 불과하니 바로 시도해보시기 바랍니다.
주석: 이번 응용프로그램 소개는 이미 알고 있는 Photon Server 지식을 기반으로 로컬 내 실행 Photon Server 환경에서 이루어지는 내용입니다. 이하 참고 문서는 다음과 같습니다.
10분만 투자하면 구축할 수 있는 매우 간편한 채팅 서버
우선적으로 Photon Server의 Application & Peer을 이해하고 나면 바로 프로젝트를 구현할 수 있습니다.
- Photon Engine 홈페이지에서Photon Server SDK를 다운로드한 후 압축을 해제하고 설치하세요.
- Visual Studio를 이용해 ChatServer(새 클래스 라이브러리 프로젝트) 구축
- 이하 세 가지 참고 추가:
dll,
Photon.SocketServer.dll
PhotonHostRuntimeInterfaces.dll
지금 Photon.SocketServer.ApplicationBase를 기반으로 한 새로운 유형의 ChatServer를 구축해 응용 앱 진입로로 삼아보세요.
APP code:
using Photon.SocketServer;
public class ChatServer : ApplicationBase
{
protected override PeerBase CreatePeer(InitRequest initRequest)
{
}
protected override void Setup()
{
}
protected override void TearDown()
{
}
}
이어서, Photon.SocketServer.ClientPeer 유형을 기반으로 한 ChatPeer를 구축합니다.
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
public class ChatPeer : ClientPeer
{
public ChatPeer(InitRequest initRequest):base(initRequest)
{
// 당사 ChatPeer 초기화
}
protected override void OnDisconnect(DisconnectReason disconnectCode, string reasonDetail)
{
// 오프라인 시 처리
}
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
// 잠시 후 언급, 클라이언트 응답에 사용하는 경우 이곳에서 추가 작업이 필요합니다.
}
}
ChatServer.CreatePeer 내 새로운 실체인 ChatPeer 구축 및 백패스
protected override PeerBase CreatePeer(InitRequest initRequest)
{
return new ChatPeer(initRequest);
}
저희는 ChatServer 응용프로그램이 서버 내부에 설정되어 실행되는 Photon 실체 안에서 Photon이 기본 코어로 로드되길 바랍니다. 따라서 저희 서버 내 설정 파일인 PhotonServer.config에 해당 응용프로그램에 관한 정의가 필요합니다. 하단의 간편한 설정 방법을 참고하세요.
<ChatServer DisplayName="Chat Server">
<TCPListeners>
<TCPListener
IPAddress="0.0.0.0"
Port="4530"
OverrideApplication="ChatServer"
>
</TCPListener>
</TCPListeners>
<! -- Defines the Photon Runtime Assembly to use. -->
<Runtime
Assembly="PhotonHostRuntime, Culture=neutral"
Type="PhotonHostRuntime.PhotonDomainManager"
UnhandledExceptionPolicy="Ignore">
</Runtime>
<! -- 그외 정의 -->
<Applications Default="ChatServer">
<Application
Name="ChatServer"
BaseDirectory="ChatServer"
Assembly="ChatServer"
Type="ChatServer">
</Application>
<! -- 그외 애플리케이션 정의 -->
</Applications>
<! -- 그외 정의 -->
</ChatServer>
상단 설정대로 기록해 당사 서비스(컴파일한 이진 코드 파일)를 deploy/ChatServer/bin에 설치해야합니다. 다른 네임스페이스에 놓지마시기 바랍니다.
Photon Server에 관한 더 자세한 설정 및 구성 내용은 아래 문서를 참고해주세요.
Chat Client 간편 채팅방 클라이언트
당사 채팅 서버의 테스트를 신속하게 진행하고 싶은 마음에 저희도 Visual Studio로 Console Project를 구축해 채팅 클라이언트로 사용했습니다. 주의: 해당 새 프로젝트에 다음 참고 파일 하나를 입력해야 합니다. Photon3DotNet.dll.
이하 간단한 테스트 코드:
using System;
using System.Collections.Generic;
using ExitGames.Client.Photon;
using System.Threading;
public class ChatClient : IPhotonPeerListener
{
private bool connected;
PhotonPeer peer;
public static void Main()
{
var client = new ChatClient();
client.peer = new PhotonPeer(client, ConnectionProtocol.Tcp);
// connect
client.DebugReturn(DebugLevel.INFO, "Connecting to server at 127.0.0.1:4530 using TCP");
client.peer.Connect("127.0.0.1:4530", "ChatServer");
// client needs a background thread to dispatch incoming messages and send outgoing messages
client.Run();
while (true)
{
if (!client.connected) { continue; }
// read input
string buffer = Console.ReadLine();
// send to server
var parameters = new Dictionary<byte, object> { { 1, buffer } };
client.peer.OpCustom(1, parameters, true);
}
}
private void UpdateLoop()
{
while (true)
{
peer.Service();
}
}
public void Run()
{
Thread thread = new Thread(UpdateLoop);
thread.IsBackground = true;
thread.Start();
}
#region IPhotonPeerListener
public void DebugReturn(DebugLevel level, string message)
{
Console.WriteLine(string.Format("{0}: {1}", level, message));
}
public void OnEvent(EventData eventData)
{
DebugReturn(DebugLevel.INFO, eventData.ToStringFull());
if (eventData.Code == 1)
{
DebugReturn(DebugLevel.INFO, string.Format("Chat Message: {0}", eventData.Parameters[1]));
}
}
public void OnMessage(object messages)
{
throw new NotImplementedException();
}
public void OnOperationResponse(OperationResponse operationResponse)
{
DebugReturn(DebugLevel.INFO, operationResponse.ToStringFull());
}
public void OnStatusChanged(StatusCode statusCode)
{
if (statusCode == StatusCode.Connect)
{
connected = true;
}
switch (statusCode)
{
case StatusCode.Connect:
DebugReturn(DebugLevel.INFO, "Connected");
connected = true;
break;
default:
DebugReturn(DebugLevel.ERROR, statusCode.ToString());
break;
}
}
#endregion
}
이제 저희의 Photon Server 및 해당 명령 라인의 ChatClient를 부팅하려고 합니다. 해당 ChatClient는 로컬 측의 ChatServer( IP:포트가 정확할 경우)와 연결할 수 있으며 문자 정보 발송도 가능합니다.
이 외에, ChatServer에는 아직 전송받은 정보에 대한 처리 로직이 없습니다. 수신한 정보를 검증하고 싶다면 ChatPeer.OnOperationRequest에서 ACK에 반응해 Peer로 되돌아가야 합니다. 반응 표기법은 다음과 같습니다.
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
// 동작에 대한 반응을 보내(~ACK) Peer로 복귀
var response = new OperationResponse(operationRequest.OperationCode);
SendOperationResponse(response, sendParameters);
}
지금은 ChatClient에서 EventCode 및 전송한 채팅 문자 정보를 출력할 수 있습니다.
이어서, 다른 클리아이언트에서 이러한 문자 정보를 수신하고자 합니다. 이에 저희는 Publish/Subscribe(발행/구독) 설계 패턴을 이용해 ChatPeer를 구현할 수 있습니다.
간단한 구현 프로그램 코드:
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
using System;
public class ChatPeer : ClientPeer
{
public ChatPeer(InitRequest request)
: base(request)
{
BroadcastMessage += OnBroadcastMessage;
}
private static event Action<ChatPeer, EventData, SendParameters> BroadcastMessage;
protected override void OnDisconnect(DisconnectReason disconnectCode, string reasonDetail)
{
BroadcastMessage -= OnBroadcastMessage;
}
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
if (operationRequest.OperationCode == 1) // Chat Custom Operation Code = 1
{
// broadcast chat custom event to other peers
var eventData = new EventData(1) { Parameters = operationRequest.Parameters }; // Chat Custom Event Code = 1
BroadcastMessage(this, eventData, sendParameters);
// send operation response (~ACK) back to peer
var response = new OperationResponse(operationRequest.OperationCode);
SendOperationResponse(response, sendParameters);
}
}
private void OnBroadcastMessage(ChatPeer peer, EventData eventData, SendParameters sendParameters)
{
if (peer ! = this) // do not send chat custom event to peer who called the chat custom operation
{
SendEvent(eventData, sendParameters);
}
}
}
이렇게 하면 지금 두 개의 ChatClient 프로그램을 실행해도 두 클라이언트 모두 정보를 상호 교환할 수 있습니다. 물론 ChatServer 프로그램 업데이트 후에는 반드시 부팅이나 재부팅을 통해 저희의 가장 중요한 Photon Server와 업데이트 후의 구성 설정 파일을 적용해야 합니다.
Photon Server 초기화에 문제가 발생할 경우, 아래의 설치 부분을 참고할 수 있습니다.
간단하죠! 여기에서 언급한 방법대로 진행하니 10분 안에 충분히 구현할 수 있지 않나요? 저희는 비록 이 문서를 작성할 때 많은 시간을 투자했지만, 상기 내용대로 진행하면 시간을 크게 단축할 수 있습니다. 이를 따라 핵심적이면서도 단순한 구조를 개발하면 즉각적으로 표정 이모티콘만 전송, 단어 필터링, 친구 목록 등의 기능을 구현하는 여러 고급 응용프로그램을 구성할 수 있습니다.
아시겠죠? 다중 사용자 응용프로그램을 개발하려면 네트워크 기술문서 및 명사 연구에 투자해야 할 시간을 단축할 수 있으며 특히 네트워크 인프라에 상관없이 신속하게 응용프로그램과 비즈니스 로직을 개발할 수 있습니다. 이러한 특징이 바로 Photon Engine의 강점 중 하나입니다!
이후 고급 문서에서도 지속적으로 서버 응용프로그램과 설정 구성 파일 내 다른 세부적인 설정 내용이 언급되오니 계속해서 깊은 관심 부탁드립니다!
댓글
댓글 0개
댓글을 남기려면 로그인하세요.