반응형
연동
- 지금까지 만들어둔 서버를 활용
- 유니티 프로젝트를 클라이언트로서 사용
- 그러나 모든 c# 메소드들이 유니티에서 그대로 동작한다는 보장은 없음
- 우선 프로젝트를 만들어서 ServerCore와 DummyClient를 옮긴다
- 그리고 PacketHandler를 수정해보자
using ServerCore;
using UnityEngine;
using DummyClient;
class PacketHandler
{
public static void S_ChatHandler(PacketSession session, IPacket packet)
{
S_Chat chatPacket = packet as S_Chat;
ServerSession serverSession = session as ServerSession;
if (chatPacket.playerId == 1)
{
Debug.Log(chatPacket.chat);
GameObject go = GameObject.Find("Player");
if(!go)
{
Debug.Log("Player not found");
}
else
{
Debug.Log("Player found");
}
}
}
}
- 실행을 해보면, 첫 chat 로그가 뜬 이후로 멈춰버린다
- 유니티 관련 코드는 메인 쓰레드가 아닌 다른 쓰레드에서 실행되지 못하게 막아져있기 때문!
- 아래와 같이 해결해보자
- 패킷을 핸들러로 바로 처리하는 것이 아니라, 큐에다가 밀어서, 유니티 쓰레드에서 처리를 하게 하자
public class NetworkManager : MonoBehaviour
{
ServerSession _session = new ServerSession();
void Start()
{
//DNS 사용
string host = Dns.GetHostName(); //내 로컬 컴퓨터의 호스트 이름
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); //주소, 포트번호
Connector connector = new Connector();
connector.Connect(endPoint,
() => { return _session; },
1);
StartCoroutine(CoSendPacket());
}
void Update()
{
IPacket packet = PacketQueue.Instance.Pop();
if(packet != null)
{
PacketManager.Instance.HandlePacket(_session, packet);
}
}
IEnumerator CoSendPacket()
{
while(true)
{
yield return new WaitForSeconds(1f);
C_Chat chatPacket = new C_Chat();
chatPacket.chat = "Hello Unity!";
ArraySegment<byte> segment = chatPacket.Write();
_session.Send(segment);
}
}
}
public class PacketQueue
{
public static PacketQueue Instance { get; } = new PacketQueue();
Queue<IPacket> _packetQueue = new Queue<IPacket> ();
object _lock = new object ();
public void Push(IPacket packet)
{
_packetQueue.Enqueue (packet);
}
public IPacket Pop()
{
lock (_lock)
{
if (_packetQueue.Count == 0)
return null;
return _packetQueue.Dequeue ();
}
}
}
class PacketManager
{
#region Singleton
static PacketManager _instance = new PacketManager();
public static PacketManager Instance { get { return _instance; } }
#endregion
T MakePacket<T>(PacketSession session, ArraySegment<byte> buffer) where T : IPacket, new()
{
T pkt = new T();
pkt.Read(buffer);
return pkt;
}
public void HandlePacket(PacketSession session, IPacket packet)
{
Action<PacketSession, IPacket> action = null;
if (_handler.TryGetValue(packet.Protocol, out action))
action.Invoke(session, packet);
}
}
반응형
'Unity' 카테고리의 다른 글
[Unity] 유니티에서 Json을 사용하는 방법 (0) | 2024.07.11 |
---|---|
[Unity][2D] 타일에서 셀 단위 이동하기 (0) | 2024.06.26 |
[Unity] 에디터에 툴바 추가하기 (0) | 2024.06.25 |