Skip to content

Instantly share code, notes, and snippets.

@oshinko
Last active April 25, 2018 17:03
Show Gist options
  • Save oshinko/80c8c312c9d9f95b7b74e9649f1ed95d to your computer and use it in GitHub Desktop.
Save oshinko/80c8c312c9d9f95b7b74e9649f1ed95d to your computer and use it in GitHub Desktop.
using Messengers.Udp;
using System.Net;
using System.Threading;
using UnityEngine;
namespace UdpExample.Client
{
public class DevServer : MonoBehaviour
{
public Messenger Messenger;
#if UNITY_EDITOR
Thread Service;
void StartServer()
{
Server.Start(IPAddress.Parse(Messenger.Host), Messenger.Port);
}
void OnEnable()
{
// アクティブ時にスレッドを開始.
Service = new Thread(new ThreadStart(StartServer));
Service.Start();
}
void OnDisable()
{
// 非アクティブ時にスレッドを終了.
Service.Abort();
}
#endif
}
}
/Applications/Unity/Unity.app/Contents/MacOS/Unity \
-batchmode \
-quit \
-projectPath ~/Projects/unity-messengers \
-executeMethod UdpExample.Server.Start \
-executeMethodArgs 8080
tail -f ~/Library/Logs/Unity/Editor.log
using Messengers;
using System.IO;
using System.Text;
namespace UdpExample.Messages
{
public class FreeMessageSerializer : ISerializer<FreeMessage>
{
Encoding Encoding = Encoding.UTF8;
public void Serialize(Stream stream, FreeMessage message)
{
stream.WriteByte((byte)message.Theme);
byte[] buffer = Encoding.GetBytes(message.Text);
stream.Write(buffer, 0, buffer.Length);
}
public FreeMessage Deserialize(Stream stream)
{
if (stream.CanRead)
{
var theme = (Theme)stream.ReadByte();
if (theme == Theme.Free)
{
var result = new FreeMessage();
using (var reader = new StreamReader(stream, Encoding))
{
result.Text = reader.ReadToEnd();
}
return result;
}
}
return null;
}
}
}
using System.IO;
namespace Messengers
{
public interface ISerializer<T>
{
void Serialize(Stream stream, T message);
T Deserialize(Stream stream);
}
}
IEnumerator Receive()
{
IPEndPoint endpoint = null;
while (true)
{
// Socket.Poll で到着を待機.
yield return new Poll(Client.Client);
if (Client.Available > 0)
{
// 以下、受信処理.
byte[] message = Client.Receive(ref endpoint);
if (message.Length > MaxDataSize)
{
Debug.LogError("Data size is too large.");
}
else if (endpoint.Equals(Remote))
{
LastReceived = Time.realtimeSinceStartup;
Available = true;
// Consume messages.
Consumers.ForEach(a => a(message));
}
}
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using UdpExample.Messages;
using UnityEngine;
namespace UdpExample
{
public class Server
{
const int DefaultPort = 8080;
// サイレントモードでのみ呼び出される想定の起動処理.
public static void Start()
{
int port = DefaultPort;
string[] args = Environment.GetCommandLineArgs();
for (var i = 0; i < args.Length; i++)
{
if (args[i] == "-executeMethodArgs" &&
i + 1 < args.Length &&
int.TryParse(args[++i], out port) &&
port < 0)
{
// 独自に定義した引数のポート番号が不正だった場合.
Debug.LogError("Invalid port number");
port = DefaultPort;
break;
}
}
Start(IPAddress.Any, port);
}
// エディタでの再生時のみ呼び出される想定の起動処理.
public static void Start(IPAddress addr, int port)
{
Debug.LogFormat("[Server] Service is available at {0}:{1}", addr, port);
var udp = new UdpClient(new IPEndPoint(addr, port));
IPEndPoint from = null;
var freeMessageSerializer = new FreeMessageSerializer();
while (true)
{
byte[] message = udp.Receive(ref from);
if (message.Length > 0)
{
var theme = (Theme)message[0];
if (theme == Theme.Check)
{
// 確認メッセージの返信.
Debug.Log("[Server] Received: ping");
udp.Send(new byte[] { (byte)Theme.Check }, 1, from);
}
else if (theme == Theme.Free)
{
// 自由メッセージの返信.
var stream = new MemoryStream(message);
FreeMessage deserialized = freeMessageSerializer.Deserialize(stream);
Debug.Log("[Server] Received: " + deserialized.Text);
Debug.Log("[Server] Length: " + message.Length);
deserialized.Text = "Thanks!";
stream = new MemoryStream();
freeMessageSerializer.Serialize(stream, deserialized);
byte[] buffer = stream.ToArray();
udp.Send(buffer, buffer.Length, from);
}
}
else
{
Debug.LogError("[Server] Received message size is zero.");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment