목차
'Unity3D' 카테고리의 다른 글
Tcp 라이브러리 - Unity3D 통신시 사용(멀티클라이언트 접속) (0) | 2017.01.20 |
---|---|
Unity Editor에서 코루틴 사용하기 (0) | 2017.01.11 |
목차
Packet.cs
using System;namespace Unity.Network{public enum PacketType{None, Connect, Reconnect, Disconnect, Chat,}[Serializable]public class Packet{public PacketType Type;}[Serializable]public class Connect : Packet{public string UserName;}[Serializable]public class ChatMessage : Packet{public string Message;}}
PacketBinder.cs
using System;
using System.Reflection;
using System.Runtime.Serialization;
namespace Unity.Network
{
sealed class PacketBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
Type returntype = null;
assemblyName = Assembly.GetExecutingAssembly().FullName;
string sharedAssemblyName = "SharedAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
typeName = typeName.Replace(sharedAssemblyName, assemblyName);
returntype = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
return returntype;
}
}
}
LocalClient.cs
using System;
using System.IO;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
namespace Unity.Network
{
public class LocalClient
{
private const string LocalIp = "127.0.0.1";
public const int PortNumber = 10001;
private const int BufferSize = 2048;
private NetworkStream _stream;
public NetworkStream Stream
{
get { return _stream; }
}
private readonly BinaryFormatter _formatter;
private TcpClient _client;
private byte[] _buffer;
public string UserName { get; set; }
public event Connected OnConnected;
public event Disconnected OnDisconnected;
public event ConnectError OnConnectError;
public event ReceiveObject OnReceiveObject;
/// <summary>
/// 클라이언트용 생성자
/// </summary>
public LocalClient() : this(null)
{
}
/// <summary>
/// 서버용 생성자
/// </summary>
/// <param name="client">이미 생성된 TcpClient</param>
public LocalClient(TcpClient client)
{
_client = client;
_formatter = new BinaryFormatter();
_formatter.Binder = new PacketBinder();
_buffer = new byte[BufferSize];
}
public void Start()
{
if (_client != null)
{
_stream = _client.GetStream();
//서버 -> 클라이언트
BeginRead();
}
else
{
//클라이언트 -> 서버
StartClient();
}
}
private void StartClient()
{
//클라이언트 -> 서버
_client = new TcpClient();
try
{
_client.BeginConnect(LocalIp, PortNumber, EndConnect, null);
}
catch (SocketException ex)
{
if (OnConnectError != null)
OnConnectError(ex);
}
}
private void EndConnect(IAsyncResult result)
{
try
{
_client.EndConnect(result);
_stream = _client.GetStream();
if (OnConnected != null)
OnConnected(this);
BeginRead();
}
catch (SocketException ex)
{
if (OnConnectError != null)
OnConnectError(ex);
}
}
private void BeginRead()
{
_stream.BeginRead(_buffer, 0, BufferSize, new AsyncCallback(ReadObject), null);
}
public void Close()
{
_stream.Close();
_client.Close();
}
private void ReadObject(IAsyncResult result)
{
int readSize = 0;
try
{
lock (_stream)
{
readSize = _stream.EndRead(result);
}
if (readSize < 1)
throw new Exception("Disconnect");
Packet packet = new Packet();
using (MemoryStream stream = new MemoryStream(_buffer))
{
packet = (Packet)_formatter.Deserialize(stream);
}
if (OnReceiveObject != null)
OnReceiveObject(this, packet);
lock (_stream)
{
BeginRead();
}
}
catch(Exception ex)
{
if (OnDisconnected != null)
OnDisconnected(this, ex);
}
}
public void SendPacket(Packet packet)
{
byte[] data = null;
try
{
using (MemoryStream stream = new MemoryStream())
{
_formatter.Serialize(stream, packet);
data = stream.ToArray();
}
if (data == null || data.Length < 1)
return;
_stream.Write(data, 0, data.Length);
_stream.Flush();
}
catch
{
}//try
}
}
public delegate void Connected(LocalClient client);
public delegate void Disconnected(LocalClient client, Exception ex);
public delegate void ConnectError(SocketException ex);
public delegate void ReceiveObject(LocalClient client, Packet packet);
}
NetMultiServer.cs
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using Unity.Network;
namespace CsConnector
{
public class NetMultiServer
{
private readonly TcpListener _listener;
private readonly Dictionary<string, LocalClient> _clientTable;
private readonly Thread _listenerThread;
public NetMultiServer()
{
_clientTable = new Dictionary<string, LocalClient>();
_listener = new TcpListener(System.Net.IPAddress.Any, LocalClient.PortNumber);
_listenerThread = new Thread(new ThreadStart(DoListen));
}
public void Start()
{
_listenerThread.Start();
}
public void Close()
{
_listener.Stop();
}
private void DoListen()
{
try
{
_listener.Start();
do
{
TcpClient tcpClient = _listener.AcceptTcpClient();
LocalClient localClient = new LocalClient(tcpClient);
localClient.OnReceiveObject += ReceiveObject;
localClient.Start();
}
while (true);
}
catch (Exception)
{
}//try
}
private void ReceiveObject(LocalClient client, Packet packet)
{
if (packet == null)
return;
switch (packet.Type)
{
case PacketType.Connect: OnConnected(client, packet); break;
}
}
private void OnConnected(LocalClient client, Packet packet)
{
Connect connect = packet as Connect;
if (connect == null)
return;
client.UserName = connect.UserName;
_clientTable.Add(client.UserName, client);
}
private void SendPacket(LocalClient client, Packet packet)
{
client.SendPacket(packet);
}
}
}
NetClient.cs
using System;
using Unity.Network;
using UnityEngine;
public class NetClient
{
private const string UserName = "UnityClient";
private LocalClient _client;
public event Chat OnChat;
public NetClient()
{
}
public void Start()
{
_client = new LocalClient();
_client.OnConnected += Connected;
_client.Start();
}
public void Close()
{
_client.Close();
}
private void Connected(LocalClient client)
{
Connect connect = new Connect()
{
Type = PacketType.Connect,
UserName = UserName,
};
_client.UserName = UserName;
_client.SendPacket(connect);
}
private void ConnectError(Exception ex)
{
Debug.Log("접속 에러\n" + ex.ToString());
}
private void ReceiveObject(LocalClient client, Packet packet)
{
if (packet == null)
return;
switch (packet.Type)
{
case PacketType.Chat: OnChatMessage(client, packet); break;
}
}
private void OnChatMessage(LocalClient client, Packet packet)
{
ChatMessage message = packet as ChatMessage;
if (message == null)
return;
if (OnChat != null)
OnChat(message.Message);
}
private void SendPacket(LocalClient client, Packet packet)
{
client.SendPacket(packet);
}
public delegate void Chat(string message);
}
'Unity3D' 카테고리의 다른 글
Tcp 소켓 사용, Unity3D+Winform 메시지 주고받기 (0) | 2017.01.24 |
---|---|
Unity Editor에서 코루틴 사용하기 (0) | 2017.01.11 |
목차
CoroutineRunner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
public static class CoroutineRunner
{
private static List _coroutineList = null;
private static List _bufferList = null;
public static IEnumerator Start(IEnumerator iterator)
{
if (_coroutineList == null)
_coroutineList = new List();
if (_bufferList == null)
_bufferList = new List();
if (_coroutineList.Count == 0)
EditorApplication.update += Update;
_bufferList.Add(iterator);
return iterator;
}
private static bool Find(IEnumerator iterator)
{
foreach (EditorCoroutine coroutine in _coroutineList)
{
if (coroutine.Find(iterator) == true)
return true;
}
return false;
}
private static void Update()
{
_coroutineList.RemoveAll
(
coroutine => { return coroutine.MoveNext() == false; }
);
if (_bufferList.Count > 0)
{
foreach (IEnumerator iterator in _bufferList)
{
if (Find(iterator) == false)
_coroutineList.Add(new EditorCoroutine(iterator));
}
_bufferList.Clear();
}
if (_coroutineList.Count == 0)
{
EditorApplication.update -= Update;
}
}
private class EditorCoroutine : IEnumerator
{
private Stack _stack;
public EditorCoroutine(IEnumerator iterator)
{
_stack = new Stack();
_stack.Push(iterator);
}
public bool MoveNext()
{
IEnumerator i = _stack.Peek();
if (i.MoveNext() == true)
{
object result = i.Current;
if (result != null && result is IEnumerator)
{
_stack.Push((IEnumerator)result);
}
return true;
}
else
{
if (_stack.Count > 1)
{
_stack.Pop();
return true;
}
}
return false;
}
public void Reset()
{
throw new System.NotSupportedException(
"This Operation Is Not Supported.");
}
public object Current
{
get { return _stack.Peek().Current; }
}
public bool Find(IEnumerator iterator)
{
return _stack.Contains(iterator);
}
}
}
'Unity3D' 카테고리의 다른 글
Tcp 소켓 사용, Unity3D+Winform 메시지 주고받기 (0) | 2017.01.24 |
---|---|
Tcp 라이브러리 - Unity3D 통신시 사용(멀티클라이언트 접속) (0) | 2017.01.20 |