際際滷

際際滷Share a Scribd company logo
C# Server 襷り鍵
2013. 06. 07.
豕
Why?
 觜 
 
2
async
await
extension
method
linq
Observable
TPL
DynamicObject
Reflection
Attribute
IEnumerable
襴
3
Network
Datasheet
Database
Logic
async, await
TaskCompletionSource
Reflection
Attribute
Dynamic
XmlLinq
IEnumerable
Network
 觜襯  豌襴襯  觜蠍 IO 
4
var socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.IPv4);
// preprocess socket
var buffer = new byte[4096];
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
result => {
var received = socket.EndReceive(result);
// process packet
}, null /* state */);
TaskCompletionSource
 C++ Future + C# Task Awaitable Future
5
Network
static Task<int> ReceiveAsync(this Socket sock, byte[] buf, int off, int size)
{
var source = new TaskCompletionSource<int>(sock);
sock.BeginReceive(buf, off, size, SocketFlags.None, state =>
{
try
{
source.SetResult(socket.EndReceive(state));
}
catch (Exception e)
{
source.SetException(e);
}
}, source);
return source.Task;
}
async, await
 Task.Result 觜蠍 蠍(await), 蠏碁 貊螳  (async)
6
Network
static async Task<byte[]> ReceiveAsync(this Socket socket, int count)
{
var buffer = new byte[count];
var length = 0;
do
{
var num = await ReceiveAsync(socket, buffer, length, count);
if (num == 0)
break;
length += num;
count -= num;
} while (count > 0);
if (length != buffer.Length) throw new IOException("packet is truncated.");
return buffer;
}
async, await
7
Network
async void ReceiveLoop(Socket socket)
{
while (true)
{
var lengthBytes = await socket.ReceiveAsync(sizeof (int));
var packetBytes = await socket.ReceiveAsync(
BitConverter.ToInt32(lengthBytes, 0));
// process packet
var packet = ReadPacket(packetBytes);
_handlerMap[packet.GetType()](packet);
}
}
await 讌 讌 IO signal る, 企 Task  覃豢螻,
螳 るジ Task襯 谿場
Listener (Server)
 ClientSocket 觜蠍磯 Accept伎,
 螳 Socket襷 觜蠍磯 Packet 蠍壱伎 豌襴
8
Network
var listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
var localEndPoint = new IPEndPoint(IPAddress.Any, Port);
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
var clientSocket = await listener.AcceptAsync();
ReceiveLoop(clientSocket);
}
async method
Summary
 Socket Async 螻 襯  (.NET 企 IOCP襦 豌襴)
 async, await TaskContinuation Syntax sugar
 async, await Keyword襦 Callback  ク蟆 Network 貊 
 蠏碁覃伎 Thread Pool  朱 
(.NET Thread Pool 企 IOCP襦 蟯襴)
9
Network
Datasheet
 dynamic  朱 Xml 所鍵
 code generator襯 
10
Xml 
Xml Model
蟲
Xml Parser
蟲
   
code generator
DynamicObject
XmlDefinition ( )
general-loader
DynamicObject
 RuntimeType朱 朱 覃る 蠏 螳
 覦襯 Type 螳 覩碁Μ 譴觜伎 覩襦 XmlDefinition 
11
Datasheet
public class XmlObject : DynamicObject
{
private readonly Dictionary<string, object> _attributes;
private readonly Dictionary<string, IEnumerable<XmlObject>>
_multipleChildren;
private readonly Dictionary<string, XmlObject> _singleChildren;
public override bool TryGetMember(GetMemberBinder binder,
out object result)
{
return TryGetValue(_attributes, binder.Name, out result) ||
TryGetValue(_singleChildren, binder.Name, out result) ||
TryGetValue(_multipleChildren, binder.Name, out result);
}
DynamicObject
 Attribute襯 曙  Type 覲 覩碁Μ 
 dynamic朱 蠏狩 Model  蠏 螳
12
Datasheet
_attributes = element.Attributes.OfType<XmlAttribute>()
.ToDictionary(e => e.Name,
e => defNode.SelectAttribute(e.Name)
.ReadValue(e.Value));
<?xml version="1.0" encoding="utf-8" ?>
<World>
<Config port="40123"/>
</World>
World.Config@port : int
dynamic world = XmlObject.Load("World.xml", _def);
_listener.Port = world.Config.port;
Summary
 dynamic  貊 螳 豢(Model, Parser  覿)
 ろ襦 誤 蠏 覦 Runtime  螳
 XmlDefinition (  螳)
 覲企 觜襯 襯  蟆曙一 Model, Parser襯 Generate
(IVsSingleFileGenerator)
13
Datasheet
Database
 Reflection螻 Attribute 朱 朱 Bind 蟲
 scheme  覿 蟆曙 model 焔朱 覈 蟲 願屋 螳
14
Scheme

DataModel

Bind 蟲
nosql or generator Reflection
Reflection
 Runtime model type覲企 scheme襯 蟲豢
 螳 一危一 Serialize/Deserialize 蟲  (String螻 object  覲)
 覈 Model 螳豌企ゼ Xml襦 覲
15
Database
new XElement("Objects",
_gameObjects.Values.Select(
obj =>
new XElement("Object",
obj.GetType().GetProperties()
.Where(e => e.CanRead && e.CanWrite)
.Select(e => new XAttribute(e.Name,
SerializeValue(e.PropertyType, e.GetValue(obj, null))
)))));
覈 Property  豢
豢ロ  string朱, 曙  れ object襦
Attribute
 Runtime 蠏 螳ロ metadata襯 貊 譯殊
16
Database
[CommandHandler("npc", "襦 Npc襯 燕")]
internal bool SpawnNpc(Entity admin,
[CommandArgument("Npc 企")] string npcName,
[CommandArgument("Npc X 豺", 0)] double newX,
[CommandArgument("Npc Y 豺", 0)] double newY)
{
if (!admin.Has<Pos>())
return false;
var npc = EntityManager.Instance.Create(EntityTemplate.Ids.Npc);
npc.Get<Motion>().Dir = admin.Get<Motion>().Dir;
npc.Get<Nameplate>().Name = npcName;
npc.Get<Pos>().Assign(new Pos {X = newX, Y = newY});
覈轟伎 る 貊 蠍磯
語 る螻 蠍磯蓋 螳, type 貊 蠍磯
Summary
 model 螳豌伎 type 覲企ゼ 豕 
 Attribute襯 覿 螳ロ 襷 覲企ゼ 貊 譯殊
(DSL, 覓語, 譯殊  碁 覲企 豢螳 讌 覲伎螳 )
 Dirty Lazy襯  豕 螳
  覲企 觜襯 襯  蟆曙一 Code Generate襯 
(partial class襯   貊 狩 螳)
17
Database
Logic
 yield return  State Machine 蟇
 context 讌襯  覲 貊  
18

A

B

C
1豐 
3豐 
5豐 
Logic
Engine
Logic #1 Logic #2
IEnumerable (Coroutine)
 IEnumerable 覦 type朱 れ yield return 
 れ 襦讌 蟾讌 蠍 螳 覦
19
Logic
public IEnumerable<int> RegenerateEntry()
{
while (true)
{
var newNpc = _context.NewGameObject(ObjectType.Npc);
_context.AddGameObject(newNpc);
_context.BroadcastPacket(newNpc.ToSpawnPacket());
var newAi = new EachAi(this, newNpc);
_context.AddEntry(newAi.AiLogicEntry);
var nextInterval = _random.Next(interval) + base;
yield return nextInterval;
}
願 語蟆 願
れ 語   讌覿
IEnumerator (Coroutine)
 IEnumerator MoveNext() 襦 貊 ろ
 Current襦 yield return 蟆郁骸 螳 
20
Logic
var enumerator = RegenerateEntry().GetEnumerator();
while (enumerator.MoveNext())
{
Thread.Sleep(enumerator.Current);
}
IEnumerable襦覿 IEnumerator襯 螳語
MoveNext()襦 yield  蟲螳 貊 
yield return 覦 螳 詞. 蠍 螳襷 
 IEnumerator襯 蟯襴螻 Thread.Sleep() 覲企  襦
LogicEngine (Coroutine)
21
Logic
public void EntryLoop()
{
var prev = DateTime.Now;
while (true)
{
var now = DateTime.Now;
var delta = (now - prev).Milliseconds;
foreach (var newOne in _newLogicEntries)
{
var newEntry = new LogicEntry
{
Enumerator = newOne().GetEnumerator(),
SleepTime = 0
};
_logicEntries.Add(newEntry);
}
_newLogicEntries.Clear();
襦 豢螳 Entry襦覿
IEnumerator螳豌企ゼ
LogicEngine (Coroutine)
22
Logic
var removals = new List<LogicEntry>();
foreach (var each in _logicEntries)
{
each.SleepTime -= delta;
if (each.SleepTime >= 0)
continue;
if (!each.Enumerator.MoveNext())
removals.Add(each);
else each.SleepTime = each.Enumerator.Current;
}
_logicEntries.RemoveAll(removals.Contains);
prev = now;
const int logicInterval = 16;
Thread.Sleep(logicInterval);
}
}
 螳ロ IEnumerator 讌
 螳  襦讌 谿場 ろ
襦讌 螳 return 襭覃 MoveNext()螳 fasle襯 覦
 襭 襦讌
Summary
 IEnumerable螻 yield return 譟壱朱 coroutine 蟲
 螳 coroutine伎襷 襷 boiler plate 貊   螳
 yield return朱 襷 覲企ゼ  れ  (Unity3D Engine)
  Thread螳 LogicEngine  Entry  覿 螳
( Thread螳  蟆曙 Lfe  螳豌企  蠍壱 螻り )
 Script襯 C#朱     (?)
(c# script + roslyn + linqpad + nuget)
23
Logic
Summary
 async, await  蠍一 Network(IO) 襦蠏碁覦
 dynamic  Runtime type dispatch
 Reflection, Attribute襯  boiler plate 貊 譴願鍵
 Attribute襦 metadata襯 貊襦 蠍磯 讌 覲伎 觜 譴願鍵
 coroutine  蠍一 襦讌 襦蠏碁覦
24
覲企 , 蠏碁Μ螻 讌蟯(蠍一) 貊朱 讌 覲伎 觜 譴願鍵
 
焔 覓語 襦 覦 願屋 譴 蟆 [...]
How much faster is C++ than C#?
25
C# may not be faster, but it makes
YOU/ME faster. That's the most
important measure for what I do. :)
http://stackoverflow.com/questions/138361/how-much-faster-is-c-than-c
Ad

Recommended

Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
Seungmo Koo
蟆覯襦蠏碁覦 #0 - TCP 覦 企欧 旧覈
蟆覯襦蠏碁覦 #0 - TCP 覦 企欧 旧覈
Seungmo Koo
Iocp advanced
Iocp advanced
Nam Hyeonuk
Ndc14 覿 覯 蟲豢 ABC
Ndc14 覿 覯 蟲豢 ABC
Ho Gyu Lee
れ讌 讌譯, Winsock API - WSAPoll, Fast Loopback
れ讌 讌譯, Winsock API - WSAPoll, Fast Loopback
ル旭 豕
NDC 11 伎誤 覯 觜覦
NDC 11 伎誤 覯 觜覦
鰻禽遺12喝晦看界一鉛艶壊壊蟆覯り仰蟲
鰻禽遺12喝晦看界一鉛艶壊壊蟆覯り仰蟲
noerror
Python 蟆覯 蟾 : RPC framework ク
Python 蟆覯 蟾 : RPC framework ク
譴豌 覦
れ螳 蟆 覯 豕
れ螳 蟆 覯 豕
YEONG-CHEON YOU
煙, 蟆 覯 覈谿 - 覿 豢蟾讌, NDC2019
煙, 蟆 覯 覈谿 - 覿 豢蟾讌, NDC2019
devCAT Studio, NEXON
殊 : 螻 覯 ろ豌 Vol. 3
殊 : 螻 覯 ろ豌 Vol. 3
Heungsub Lee
[NDC 2018] 螳覦螳 覃覈襴襴 覯蟾
[NDC 2018] 螳覦螳 覃覈襴襴 覯蟾
DongMin Choi
觜蟯襴 覦 覯蟾 (2010 襭)
觜蟯襴 覦 覯蟾 (2010 襭)
YEONG-CHEON YOU
蟆 覿 覯 蟲譟
蟆 覿 覯 蟲譟
Hyunjik Bae
[KGC 2012]Boost.asio襯 伎 ろ語 襦蠏碁覦
[KGC 2012]Boost.asio襯 伎 ろ語 襦蠏碁覦
ル旭 豕
蟆覯襦蠏碁覦 #2 - IOCP Adv
蟆覯襦蠏碁覦 #2 - IOCP Adv
Seungmo Koo
FIFA 殊 3 MongoDB 蠍
FIFA 殊 3 MongoDB 蠍
Jongwon Kim
朱 危エ覲 MMORPG 狩蟆 ろ
朱 危エ覲 MMORPG 狩蟆 ろ
QooJuice
蟆覯襦蠏碁覦 #1 - IOCP
蟆覯襦蠏碁覦 #1 - IOCP
Seungmo Koo
MMOG Server-Side 豢 覦 企豌襴 り 蟲
MMOG Server-Side 豢 覦 企豌襴 り 蟲
YEONG-CHEON YOU
Modern C++ 襦蠏碁襾碁ゼ CPP11/14 旧
Modern C++ 襦蠏碁襾碁ゼ CPP11/14 旧
ル旭 豕
GCGC- CGCII 覯 讌 蠍一 (2) - Perfornance
GCGC- CGCII 覯 讌 蠍一 (2) - Perfornance
蟆覯襦蠏碁覦 #4 - 覃一る 襦蠏碁覦
蟆覯襦蠏碁覦 #4 - 覃一る 襦蠏碁覦
Seungmo Koo
蟆 覯 焔 覿蠍
蟆 覯 焔 覿蠍
iFunFactory Inc.
Next-generation MMORPG service architecture
Next-generation MMORPG service architecture
Jongwon Kim
[殊 : 螻] 覯 ろ豌 - SPOF 覿 MMORPG 覯
[殊 : 螻] 覯 ろ豌 - SPOF 覿 MMORPG 覯
Heungsub Lee
譴 覯 蟆 襦讌
譴 覯 蟆 襦讌
Hoyoung Choi
.NET 觜蠍 襦蠏碁覦 覦一郁鍵
.NET 觜蠍 襦蠏碁覦 覦一郁鍵
Seong Won Mun
Naver api for android
Naver api for android
Sangon Lee

More Related Content

What's hot (20)

れ螳 蟆 覯 豕
れ螳 蟆 覯 豕
YEONG-CHEON YOU
煙, 蟆 覯 覈谿 - 覿 豢蟾讌, NDC2019
煙, 蟆 覯 覈谿 - 覿 豢蟾讌, NDC2019
devCAT Studio, NEXON
殊 : 螻 覯 ろ豌 Vol. 3
殊 : 螻 覯 ろ豌 Vol. 3
Heungsub Lee
[NDC 2018] 螳覦螳 覃覈襴襴 覯蟾
[NDC 2018] 螳覦螳 覃覈襴襴 覯蟾
DongMin Choi
觜蟯襴 覦 覯蟾 (2010 襭)
觜蟯襴 覦 覯蟾 (2010 襭)
YEONG-CHEON YOU
蟆 覿 覯 蟲譟
蟆 覿 覯 蟲譟
Hyunjik Bae
[KGC 2012]Boost.asio襯 伎 ろ語 襦蠏碁覦
[KGC 2012]Boost.asio襯 伎 ろ語 襦蠏碁覦
ル旭 豕
蟆覯襦蠏碁覦 #2 - IOCP Adv
蟆覯襦蠏碁覦 #2 - IOCP Adv
Seungmo Koo
FIFA 殊 3 MongoDB 蠍
FIFA 殊 3 MongoDB 蠍
Jongwon Kim
朱 危エ覲 MMORPG 狩蟆 ろ
朱 危エ覲 MMORPG 狩蟆 ろ
QooJuice
蟆覯襦蠏碁覦 #1 - IOCP
蟆覯襦蠏碁覦 #1 - IOCP
Seungmo Koo
MMOG Server-Side 豢 覦 企豌襴 り 蟲
MMOG Server-Side 豢 覦 企豌襴 り 蟲
YEONG-CHEON YOU
Modern C++ 襦蠏碁襾碁ゼ CPP11/14 旧
Modern C++ 襦蠏碁襾碁ゼ CPP11/14 旧
ル旭 豕
GCGC- CGCII 覯 讌 蠍一 (2) - Perfornance
GCGC- CGCII 覯 讌 蠍一 (2) - Perfornance
蟆覯襦蠏碁覦 #4 - 覃一る 襦蠏碁覦
蟆覯襦蠏碁覦 #4 - 覃一る 襦蠏碁覦
Seungmo Koo
蟆 覯 焔 覿蠍
蟆 覯 焔 覿蠍
iFunFactory Inc.
Next-generation MMORPG service architecture
Next-generation MMORPG service architecture
Jongwon Kim
[殊 : 螻] 覯 ろ豌 - SPOF 覿 MMORPG 覯
[殊 : 螻] 覯 ろ豌 - SPOF 覿 MMORPG 覯
Heungsub Lee
譴 覯 蟆 襦讌
譴 覯 蟆 襦讌
Hoyoung Choi
煙, 蟆 覯 覈谿 - 覿 豢蟾讌, NDC2019
煙, 蟆 覯 覈谿 - 覿 豢蟾讌, NDC2019
devCAT Studio, NEXON
殊 : 螻 覯 ろ豌 Vol. 3
殊 : 螻 覯 ろ豌 Vol. 3
Heungsub Lee
[NDC 2018] 螳覦螳 覃覈襴襴 覯蟾
[NDC 2018] 螳覦螳 覃覈襴襴 覯蟾
DongMin Choi
觜蟯襴 覦 覯蟾 (2010 襭)
觜蟯襴 覦 覯蟾 (2010 襭)
YEONG-CHEON YOU
蟆 覿 覯 蟲譟
蟆 覿 覯 蟲譟
Hyunjik Bae
[KGC 2012]Boost.asio襯 伎 ろ語 襦蠏碁覦
[KGC 2012]Boost.asio襯 伎 ろ語 襦蠏碁覦
ル旭 豕
蟆覯襦蠏碁覦 #2 - IOCP Adv
蟆覯襦蠏碁覦 #2 - IOCP Adv
Seungmo Koo
FIFA 殊 3 MongoDB 蠍
FIFA 殊 3 MongoDB 蠍
Jongwon Kim
朱 危エ覲 MMORPG 狩蟆 ろ
朱 危エ覲 MMORPG 狩蟆 ろ
QooJuice
蟆覯襦蠏碁覦 #1 - IOCP
蟆覯襦蠏碁覦 #1 - IOCP
Seungmo Koo
MMOG Server-Side 豢 覦 企豌襴 り 蟲
MMOG Server-Side 豢 覦 企豌襴 り 蟲
YEONG-CHEON YOU
Modern C++ 襦蠏碁襾碁ゼ CPP11/14 旧
Modern C++ 襦蠏碁襾碁ゼ CPP11/14 旧
ル旭 豕
GCGC- CGCII 覯 讌 蠍一 (2) - Perfornance
GCGC- CGCII 覯 讌 蠍一 (2) - Perfornance
蟆覯襦蠏碁覦 #4 - 覃一る 襦蠏碁覦
蟆覯襦蠏碁覦 #4 - 覃一る 襦蠏碁覦
Seungmo Koo
Next-generation MMORPG service architecture
Next-generation MMORPG service architecture
Jongwon Kim
[殊 : 螻] 覯 ろ豌 - SPOF 覿 MMORPG 覯
[殊 : 螻] 覯 ろ豌 - SPOF 覿 MMORPG 覯
Heungsub Lee
譴 覯 蟆 襦讌
譴 覯 蟆 襦讌
Hoyoung Choi

Similar to C# Game Server (20)

.NET 觜蠍 襦蠏碁覦 覦一郁鍵
.NET 觜蠍 襦蠏碁覦 覦一郁鍵
Seong Won Mun
Naver api for android
Naver api for android
Sangon Lee
Gcd ppt
Gcd ppt
Sangon Lee
Android xml parsing
Android xml parsing
Sangon Lee
android_thread
android_thread
handfoot
Javascript 譟郁 蠍
Javascript 譟郁 蠍
jongho jeong
[れ企ろれ碁碁] Pinpoint襯 伎伎 覯襴 Apache Openwhisk 碁伎燕蠍 - れ麹
[れ企ろれ碁碁] Pinpoint襯 伎伎 覯襴 Apache Openwhisk 碁伎燕蠍 - れ麹
NAVER Engineering
Ji 螳覦 襴觀 (襴狩襦蠏碁襾)
Ji 螳覦 襴觀 (襴狩襦蠏碁襾)
beom kyun choi
pgday-2023
pgday-2023
ranaadilstories
ECMAScript 6 襦 蟆!
ECMAScript 6 襦 蟆!
WooYoung Cho
5-4. html5 offline and storage
5-4. html5 offline and storage
JinKyoungHeo
I phone 2 release
I phone 2 release
Jaehyeuk Oh
TenforFlow Internals
TenforFlow Internals
Kiho Hong
GKAC 2015 Apr. - Battery, 襦企襯 API 語
GKAC 2015 Apr. - Battery, 襦企襯 API 語
GDG Korea
C# 觜襯 螳覦
C# 觜襯 螳覦
ル旭 豕
Rx java intro
Rx java intro
Young-Hyuk Yoo
SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8
Sangmin Lee
Tensorflow service & Machine Learning
Tensorflow service & Machine Learning
JEEHYUN PAIK
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
蠍磯
20140528 AWS Meister BlackBelt - Amazon Kinesis (Korean)
20140528 AWS Meister BlackBelt - Amazon Kinesis (Korean)
Amazon Web Services Korea
.NET 觜蠍 襦蠏碁覦 覦一郁鍵
.NET 觜蠍 襦蠏碁覦 覦一郁鍵
Seong Won Mun
Naver api for android
Naver api for android
Sangon Lee
Android xml parsing
Android xml parsing
Sangon Lee
android_thread
android_thread
handfoot
Javascript 譟郁 蠍
Javascript 譟郁 蠍
jongho jeong
[れ企ろれ碁碁] Pinpoint襯 伎伎 覯襴 Apache Openwhisk 碁伎燕蠍 - れ麹
[れ企ろれ碁碁] Pinpoint襯 伎伎 覯襴 Apache Openwhisk 碁伎燕蠍 - れ麹
NAVER Engineering
Ji 螳覦 襴觀 (襴狩襦蠏碁襾)
Ji 螳覦 襴觀 (襴狩襦蠏碁襾)
beom kyun choi
ECMAScript 6 襦 蟆!
ECMAScript 6 襦 蟆!
WooYoung Cho
5-4. html5 offline and storage
5-4. html5 offline and storage
JinKyoungHeo
I phone 2 release
I phone 2 release
Jaehyeuk Oh
TenforFlow Internals
TenforFlow Internals
Kiho Hong
GKAC 2015 Apr. - Battery, 襦企襯 API 語
GKAC 2015 Apr. - Battery, 襦企襯 API 語
GDG Korea
C# 觜襯 螳覦
C# 觜襯 螳覦
ル旭 豕
SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8
Sangmin Lee
Tensorflow service & Machine Learning
Tensorflow service & Machine Learning
JEEHYUN PAIK
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
蠍磯
20140528 AWS Meister BlackBelt - Amazon Kinesis (Korean)
20140528 AWS Meister BlackBelt - Amazon Kinesis (Korean)
Amazon Web Services Korea
Ad

More from lactrious (7)

Layered System prototype
Layered System prototype
lactrious
Policy based Class Design
Policy based Class Design
lactrious
Preprocessor Programming
Preprocessor Programming
lactrious
AWS GameServer Management
AWS GameServer Management
lactrious
Index Analysis
Index Analysis
lactrious
Synchronizing concurrent threads
Synchronizing concurrent threads
lactrious
omega design proposal
omega design proposal
lactrious
Layered System prototype
Layered System prototype
lactrious
Policy based Class Design
Policy based Class Design
lactrious
Preprocessor Programming
Preprocessor Programming
lactrious
AWS GameServer Management
AWS GameServer Management
lactrious
Index Analysis
Index Analysis
lactrious
Synchronizing concurrent threads
Synchronizing concurrent threads
lactrious
omega design proposal
omega design proposal
lactrious
Ad

C# Game Server

  • 2. Why? 觜 2 async await extension method linq Observable TPL DynamicObject Reflection Attribute IEnumerable
  • 4. Network 觜襯 豌襴襯 觜蠍 IO 4 var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4); // preprocess socket var buffer = new byte[4096]; socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, result => { var received = socket.EndReceive(result); // process packet }, null /* state */);
  • 5. TaskCompletionSource C++ Future + C# Task Awaitable Future 5 Network static Task<int> ReceiveAsync(this Socket sock, byte[] buf, int off, int size) { var source = new TaskCompletionSource<int>(sock); sock.BeginReceive(buf, off, size, SocketFlags.None, state => { try { source.SetResult(socket.EndReceive(state)); } catch (Exception e) { source.SetException(e); } }, source); return source.Task; }
  • 6. async, await Task.Result 觜蠍 蠍(await), 蠏碁 貊螳 (async) 6 Network static async Task<byte[]> ReceiveAsync(this Socket socket, int count) { var buffer = new byte[count]; var length = 0; do { var num = await ReceiveAsync(socket, buffer, length, count); if (num == 0) break; length += num; count -= num; } while (count > 0); if (length != buffer.Length) throw new IOException("packet is truncated."); return buffer; }
  • 7. async, await 7 Network async void ReceiveLoop(Socket socket) { while (true) { var lengthBytes = await socket.ReceiveAsync(sizeof (int)); var packetBytes = await socket.ReceiveAsync( BitConverter.ToInt32(lengthBytes, 0)); // process packet var packet = ReadPacket(packetBytes); _handlerMap[packet.GetType()](packet); } } await 讌 讌 IO signal る, 企 Task 覃豢螻, 螳 るジ Task襯 谿場
  • 8. Listener (Server) ClientSocket 觜蠍磯 Accept伎, 螳 Socket襷 觜蠍磯 Packet 蠍壱伎 豌襴 8 Network var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); var localEndPoint = new IPEndPoint(IPAddress.Any, Port); listener.Bind(localEndPoint); listener.Listen(100); while (true) { var clientSocket = await listener.AcceptAsync(); ReceiveLoop(clientSocket); } async method
  • 9. Summary Socket Async 螻 襯 (.NET 企 IOCP襦 豌襴) async, await TaskContinuation Syntax sugar async, await Keyword襦 Callback ク蟆 Network 貊 蠏碁覃伎 Thread Pool 朱 (.NET Thread Pool 企 IOCP襦 蟯襴) 9 Network
  • 10. Datasheet dynamic 朱 Xml 所鍵 code generator襯 10 Xml Xml Model 蟲 Xml Parser 蟲 code generator DynamicObject XmlDefinition ( ) general-loader
  • 11. DynamicObject RuntimeType朱 朱 覃る 蠏 螳 覦襯 Type 螳 覩碁Μ 譴觜伎 覩襦 XmlDefinition 11 Datasheet public class XmlObject : DynamicObject { private readonly Dictionary<string, object> _attributes; private readonly Dictionary<string, IEnumerable<XmlObject>> _multipleChildren; private readonly Dictionary<string, XmlObject> _singleChildren; public override bool TryGetMember(GetMemberBinder binder, out object result) { return TryGetValue(_attributes, binder.Name, out result) || TryGetValue(_singleChildren, binder.Name, out result) || TryGetValue(_multipleChildren, binder.Name, out result); }
  • 12. DynamicObject Attribute襯 曙 Type 覲 覩碁Μ dynamic朱 蠏狩 Model 蠏 螳 12 Datasheet _attributes = element.Attributes.OfType<XmlAttribute>() .ToDictionary(e => e.Name, e => defNode.SelectAttribute(e.Name) .ReadValue(e.Value)); <?xml version="1.0" encoding="utf-8" ?> <World> <Config port="40123"/> </World> World.Config@port : int dynamic world = XmlObject.Load("World.xml", _def); _listener.Port = world.Config.port;
  • 13. Summary dynamic 貊 螳 豢(Model, Parser 覿) ろ襦 誤 蠏 覦 Runtime 螳 XmlDefinition ( 螳) 覲企 觜襯 襯 蟆曙一 Model, Parser襯 Generate (IVsSingleFileGenerator) 13 Datasheet
  • 14. Database Reflection螻 Attribute 朱 朱 Bind 蟲 scheme 覿 蟆曙 model 焔朱 覈 蟲 願屋 螳 14 Scheme DataModel Bind 蟲 nosql or generator Reflection
  • 15. Reflection Runtime model type覲企 scheme襯 蟲豢 螳 一危一 Serialize/Deserialize 蟲 (String螻 object 覲) 覈 Model 螳豌企ゼ Xml襦 覲 15 Database new XElement("Objects", _gameObjects.Values.Select( obj => new XElement("Object", obj.GetType().GetProperties() .Where(e => e.CanRead && e.CanWrite) .Select(e => new XAttribute(e.Name, SerializeValue(e.PropertyType, e.GetValue(obj, null)) ))))); 覈 Property 豢 豢ロ string朱, 曙 れ object襦
  • 16. Attribute Runtime 蠏 螳ロ metadata襯 貊 譯殊 16 Database [CommandHandler("npc", "襦 Npc襯 燕")] internal bool SpawnNpc(Entity admin, [CommandArgument("Npc 企")] string npcName, [CommandArgument("Npc X 豺", 0)] double newX, [CommandArgument("Npc Y 豺", 0)] double newY) { if (!admin.Has<Pos>()) return false; var npc = EntityManager.Instance.Create(EntityTemplate.Ids.Npc); npc.Get<Motion>().Dir = admin.Get<Motion>().Dir; npc.Get<Nameplate>().Name = npcName; npc.Get<Pos>().Assign(new Pos {X = newX, Y = newY}); 覈轟伎 る 貊 蠍磯 語 る螻 蠍磯蓋 螳, type 貊 蠍磯
  • 17. Summary model 螳豌伎 type 覲企ゼ 豕 Attribute襯 覿 螳ロ 襷 覲企ゼ 貊 譯殊 (DSL, 覓語, 譯殊 碁 覲企 豢螳 讌 覲伎螳 ) Dirty Lazy襯 豕 螳 覲企 觜襯 襯 蟆曙一 Code Generate襯 (partial class襯 貊 狩 螳) 17 Database
  • 18. Logic yield return State Machine 蟇 context 讌襯 覲 貊 18 A B C 1豐 3豐 5豐 Logic Engine Logic #1 Logic #2
  • 19. IEnumerable (Coroutine) IEnumerable 覦 type朱 れ yield return れ 襦讌 蟾讌 蠍 螳 覦 19 Logic public IEnumerable<int> RegenerateEntry() { while (true) { var newNpc = _context.NewGameObject(ObjectType.Npc); _context.AddGameObject(newNpc); _context.BroadcastPacket(newNpc.ToSpawnPacket()); var newAi = new EachAi(this, newNpc); _context.AddEntry(newAi.AiLogicEntry); var nextInterval = _random.Next(interval) + base; yield return nextInterval; } 願 語蟆 願 れ 語 讌覿
  • 20. IEnumerator (Coroutine) IEnumerator MoveNext() 襦 貊 ろ Current襦 yield return 蟆郁骸 螳 20 Logic var enumerator = RegenerateEntry().GetEnumerator(); while (enumerator.MoveNext()) { Thread.Sleep(enumerator.Current); } IEnumerable襦覿 IEnumerator襯 螳語 MoveNext()襦 yield 蟲螳 貊 yield return 覦 螳 詞. 蠍 螳襷 IEnumerator襯 蟯襴螻 Thread.Sleep() 覲企 襦
  • 21. LogicEngine (Coroutine) 21 Logic public void EntryLoop() { var prev = DateTime.Now; while (true) { var now = DateTime.Now; var delta = (now - prev).Milliseconds; foreach (var newOne in _newLogicEntries) { var newEntry = new LogicEntry { Enumerator = newOne().GetEnumerator(), SleepTime = 0 }; _logicEntries.Add(newEntry); } _newLogicEntries.Clear(); 襦 豢螳 Entry襦覿 IEnumerator螳豌企ゼ
  • 22. LogicEngine (Coroutine) 22 Logic var removals = new List<LogicEntry>(); foreach (var each in _logicEntries) { each.SleepTime -= delta; if (each.SleepTime >= 0) continue; if (!each.Enumerator.MoveNext()) removals.Add(each); else each.SleepTime = each.Enumerator.Current; } _logicEntries.RemoveAll(removals.Contains); prev = now; const int logicInterval = 16; Thread.Sleep(logicInterval); } } 螳ロ IEnumerator 讌 螳 襦讌 谿場 ろ 襦讌 螳 return 襭覃 MoveNext()螳 fasle襯 覦 襭 襦讌
  • 23. Summary IEnumerable螻 yield return 譟壱朱 coroutine 蟲 螳 coroutine伎襷 襷 boiler plate 貊 螳 yield return朱 襷 覲企ゼ れ (Unity3D Engine) Thread螳 LogicEngine Entry 覿 螳 ( Thread螳 蟆曙 Lfe 螳豌企 蠍壱 螻り ) Script襯 C#朱 (?) (c# script + roslyn + linqpad + nuget) 23 Logic
  • 24. Summary async, await 蠍一 Network(IO) 襦蠏碁覦 dynamic Runtime type dispatch Reflection, Attribute襯 boiler plate 貊 譴願鍵 Attribute襦 metadata襯 貊襦 蠍磯 讌 覲伎 觜 譴願鍵 coroutine 蠍一 襦讌 襦蠏碁覦 24 覲企 , 蠏碁Μ螻 讌蟯(蠍一) 貊朱 讌 覲伎 觜 譴願鍵 焔 覓語 襦 覦 願屋 譴 蟆 [...]
  • 25. How much faster is C++ than C#? 25 C# may not be faster, but it makes YOU/ME faster. That's the most important measure for what I do. :) http://stackoverflow.com/questions/138361/how-much-faster-is-c-than-c