diff --git a/.nuget/Client_ReadMe.txt b/.nuget/Client_ReadMe.txt
new file mode 100644
index 0000000..f1e32b2
--- /dev/null
+++ b/.nuget/Client_ReadMe.txt
@@ -0,0 +1,5 @@
+Download [Photon Server SDK] https://www.photonengine.com/en-US/OnPremise/Download
+Add and reference following dlls.
+
+lib/ExitGamesLibs.dll
+lib/Photon3DotNet.dll
\ No newline at end of file
diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config
new file mode 100644
index 0000000..67f8ea0
--- /dev/null
+++ b/.nuget/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe
new file mode 100644
index 0000000..3ffdd33
Binary files /dev/null and b/.nuget/NuGet.exe differ
diff --git a/.nuget/NuGet.targets b/.nuget/NuGet.targets
new file mode 100644
index 0000000..f943812
--- /dev/null
+++ b/.nuget/NuGet.targets
@@ -0,0 +1,144 @@
+
+
+
+ $(MSBuildProjectDirectory)\..\
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
+
+
+
+
+ $(SolutionDir).nuget
+
+
+
+ $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
+ $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
+
+
+
+ $(MSBuildProjectDirectory)\packages.config
+ $(PackagesProjectConfig)
+
+
+
+
+ $(NuGetToolsPath)\NuGet.exe
+ @(PackageSource)
+
+ "$(NuGetExePath)"
+ mono --runtime=v4.0.30319 $(NuGetExePath)
+
+ $(TargetDir.Trim('\\'))
+
+ -RequireConsent
+ -NonInteractive
+
+ "$(SolutionDir) "
+ "$(SolutionDir)"
+
+
+ $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
+ $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
+
+
+
+ RestorePackages;
+ $(BuildDependsOn);
+
+
+
+
+ $(BuildDependsOn);
+ BuildPackage;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.nuget/PhotonWire.Client.nuspec b/.nuget/PhotonWire.Client.nuspec
new file mode 100644
index 0000000..05eacdc
--- /dev/null
+++ b/.nuget/PhotonWire.Client.nuspec
@@ -0,0 +1,32 @@
+
+
+
+ PhotonWire.Client
+ 1.0.2
+ PhotonWire.Client
+ neuecc
+ neuecc
+ false
+ Typed Asynchronous RPC Layer for Photon Server. This package is for .NET client implementation.
+
+
+
+ en-US
+ http://opensource.org/licenses/MIT
+ https://github.com/neuecc/PhotonWire
+ Photon MultiPlayer Distributed websockets streaming realtime unity
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/PhotonWire.Server.nuspec b/.nuget/PhotonWire.Server.nuspec
new file mode 100644
index 0000000..7978873
--- /dev/null
+++ b/.nuget/PhotonWire.Server.nuspec
@@ -0,0 +1,31 @@
+
+
+
+ PhotonWire.Server
+ 1.0.2
+ PhotonWire.Server
+ neuecc
+ neuecc
+ false
+ Typed Asynchronous RPC Layer for Photon Server. This package is for realtime server implementation.
+
+
+
+ en-US
+ http://opensource.org/licenses/MIT
+ https://github.com/neuecc/PhotonWire
+ Photon MultiPlayer Distributed websockets streaming realtime unity
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/PhotonWire.nuspec b/.nuget/PhotonWire.nuspec
new file mode 100644
index 0000000..25c2378
--- /dev/null
+++ b/.nuget/PhotonWire.nuspec
@@ -0,0 +1,28 @@
+
+
+
+ PhotonWire
+ 1.0.2
+ PhotonWire
+ neuecc
+ neuecc
+ false
+ Typed Asynchronous RPC Layer for Photon Server. This package includes Server libs + Analyzer + HubInvoker
+
+
+
+ en-US
+ http://opensource.org/licenses/MIT
+ https://github.com/neuecc/PhotonWire
+ Photon MultiPlayer Distributed websockets streaming realtime unity
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/Server_ReadMe.txt b/.nuget/Server_ReadMe.txt
new file mode 100644
index 0000000..e19ea38
--- /dev/null
+++ b/.nuget/Server_ReadMe.txt
@@ -0,0 +1,102 @@
+Package does not includes Photon SDK,
+please download from [Photon Server SDK]
+https://www.photonengine.com/en-US/OnPremise/Download
+Add and reference following dlls.
+
+lib/ExitGamesLibs.dll
+lib/Photon.SocketServer.dll
+lib/PhotonHostRuntimeInterfaces.dll
+
+And PhotonSocketServer.exe binary copy to $(SolutionDir)\PhotonLibs\bin_Win64
+
+PhotonWire.HubInvoker is in packages\PhotonWire\tools\
+
+---
+
+1. Create Startup.cs
+
+```
+using PhotonWire.Server;
+
+public class Startup : PhotonWireApplicationBase
+{
+
+}
+```
+
+2. Create Hub
+
+```csharp
+using PhotonWire.Server;
+
+[Hub(0)]
+public class MyFirstHub : Hub
+{
+ [Operation(0)]
+ public int Sum(int x, int y)
+ {
+ return x + y;
+ }
+}
+```
+
+3. Create PhotonServer.config (must be UTF-8 without BOM)
+
+```xml
+
+
+
+
+
+
+
+
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+4. Setup VisualStudio debugging option
+
+// Start external program:
+/* Absolute Dir Paths */\PhotonLibs\bin_Win64\PhotonSocketServer.exe
+
+// Star Options, Command line arguments:
+/debug GettingStarted /config GettingStarted.Server\bin\PhotonServer.config
+
+// Star Options, Working directory:
+/* Absolute Path */\PhotonLibs\
\ No newline at end of file
diff --git a/.nuget/pack.bat b/.nuget/pack.bat
new file mode 100644
index 0000000..895206f
--- /dev/null
+++ b/.nuget/pack.bat
@@ -0,0 +1,3 @@
+nuget pack PhotonWire.nuspec
+nuget pack PhotonWire.Server.nuspec
+nuget pack PhotonWire.Client.nuspec
\ No newline at end of file
diff --git a/.nuget/push.bat b/.nuget/push.bat
new file mode 100644
index 0000000..5e635e4
--- /dev/null
+++ b/.nuget/push.bat
@@ -0,0 +1,4 @@
+nuget push PhotonWire.1.0.2.nupkg
+nuget push PhotonWire.Server.1.0.2.nupkg
+nuget push PhotonWire.Client.1.0.2.nupkg
+nuget push ..\Source\PhotonWire.Analyzer\bin\Release\PhotonWire.Analyzer.1.0.2.0.nupkg
\ No newline at end of file
diff --git a/PhotonWire.sln b/PhotonWire.sln
index 9d93253..7abe934 100644
--- a/PhotonWire.sln
+++ b/PhotonWire.sln
@@ -4,9 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{7341F80B-AC69-42CA-BBDC-3BD667C7C640}"
- ProjectSection(SolutionItems) = preProject
- VSDocToMarkdown.csx = VSDocToMarkdown.csx
- EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample", "Sample", "{8C25F347-E802-4BFF-BBA7-5EFA3E8CB03A}"
EndProject
@@ -36,8 +33,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotonWire.UnityClient.CSha
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F69EC9CD-AD54-4725-BF65-40C2D488E465}"
ProjectSection(SolutionItems) = preProject
+ .nuget\Client_ReadMe.txt = .nuget\Client_ReadMe.txt
+ .nuget\pack.bat = .nuget\pack.bat
+ .nuget\PhotonWire.Client.nuspec = .nuget\PhotonWire.Client.nuspec
+ .nuget\PhotonWire.nuspec = .nuget\PhotonWire.nuspec
+ .nuget\PhotonWire.Server.nuspec = .nuget\PhotonWire.Server.nuspec
+ .nuget\push.bat = .nuget\push.bat
README.md = README.md
- VSDocToMarkdown.csx = VSDocToMarkdown.csx
+ .nuget\Server_ReadMe.txt = .nuget\Server_ReadMe.txt
EndProjectSection
EndProject
Global
diff --git a/README.md b/README.md
index ef53189..a355c51 100644
--- a/README.md
+++ b/README.md
@@ -2,50 +2,765 @@ PhotonWire
===
Typed Asynchronous RPC Layer for Photon Server + Unity
-Document
+What is PhotonWire?
---
-Coming Soon...
+PhotonWire provides client-server RPC with Photon Unity Native SDK and and server-server RPC with Photon Server SDK. PhotonWire mainly aims to fully controll server side logic.
-Download from Photon Server SDK
-https://www.photonengine.com/en-US/OnPremise/Download
+* TypeSafe, Server-Server uses dynamic proxy, Client-Server uses T4 pre-generate
+* HighPerformance, Fully Asynchronous(Server is async/await, Client is UniRx) and pre-generated serializer by [MsgPack](http://msgpack.org/)
+* Fully integrated with Visual Studio
+* Tools, PhotonWire.HubInvoker can invoke API directly
-under deloy/bin_Win64
+Getting Started - Server
+---
+In Visual Studio(2015 or higher), create new .NET 4.6(or higher) `Class Library Project`. For example sample project name - `GettingStarted.Server`.
+
+In Package Manager Console, add PhotonWire NuGet package.
+
+* PM> Install-Package PhotonWire
+
+It includes `PhotonWire.Server` and `PhotonWire.Analyzer`.
+
+Package does not includes Photon SDK, please download from [Photon Server SDK](https://www.photonengine.com/en-US/OnPremise/Download). Server Project needs `lib/ExitGamesLibs.dll`, `lib/Photon.SocketServer.dll` and `lib/PhotonHostRuntimeInterfaces.dll`.
+
+```csharp
+using PhotonWire.Server;
+
+namespace GettingStarted.Server
+{
+ // Application Entrypoint for Photon Server.
+ public class Startup : PhotonWireApplicationBase
+ {
+
+ }
+}
+```
+
+Okay, Let's create API! Add C# class file `MyFirstHub.cs`.
+
+```csharp
+using PhotonWire.Server;
-for Server Project
-lib/ExitGamesLibs.dll
-lib/Photon.SocketServer.dll
-lib/PhotonHostRuntimeInterfaces.dll
+namespace GettingStarted.Server
+{
+ [Hub(0)]
+ public class MyFirstHub : Hub
+ {
+ [Operation(0)]
+ public int Sum(int x, int y)
+ {
+ return x + y;
+ }
+ }
+}
+```
-for .NET Clinet Project
-lib/ExitGamesLibs.dll
-lib/Photon3DotNet.dll
+![image](https://cloud.githubusercontent.com/assets/46207/15641589/f703ccb2-267c-11e6-8aa2-9a919bdbbecd.png)
-for Unity Project
-lib /Photon3Unity3D.dll
+Hub Type needs `HubAttribute` and Method needs `OperationAttribute`. `PhotonWire.Analyzer` detects there rules. You may only follow it.
+Configuration sample. config file *must be UTF8 without BOM*.
-ServerApp Copy dll
+```xml
+
+
+
+
-Build Events -> Post-build event commandline
+
+
+
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+And modify property, Copy to Output Directory `Copy always`
+
+![image](https://cloud.githubusercontent.com/assets/46207/15642096/125b4a1e-2680-11e6-98e5-6d9e0a0353e4.png)
+
+Here is the result of Project Structure.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15641797/2fdba392-267e-11e6-8244-0428adbe150a.png)
+
+Start and Debug Server Codes on Visual Studio
+---
+PhotonWire application is hosted by `PhotonSocketServer.exe`. `PhotonSocketServer.exe` is in Photon Server SDK, copy from `deploy/bin_64` to `$(SolutionDir)\PhotonLibs\bin_Win64`.
-xcopy "$(TargetDir)*.*" "$(SolutionDir)..\PhotonLibs\$(ProjectName)\bin\" /Y /Q
+Open Project Properties -> Build Events, write Post-build event commandline:
+```
+xcopy "$(TargetDir)*.*" "$(SolutionDir)\PhotonLibs\$(ProjectName)\bin\" /Y /Q
+```
+In Debug tab, set up three definitions.
-Debug
--> Start external program:
+![image](https://cloud.githubusercontent.com/assets/46207/15642631/894128b2-2683-11e6-88b9-69665699fd56.png)
+
+```
+// Start external program:
/* Absolute Dir Paths */\PhotonLibs\bin_Win64\PhotonSocketServer.exe
--> Star Options
-/debug PhotonWireSample /config PhotonWire.Sample.ServerApp\bin\PhotonServer.config
+// Star Options, Command line arguments:
+/debug GettingStarted /config GettingStarted.Server\bin\PhotonServer.config
--> Working directory:
+// Star Options, Working directory:
/* Absolute Path */\PhotonLibs\
+```
+
+Press `F5` to start debugging. If cannot start debugging, please see log. Log exists under `PhotonLibs\log`. If encounts `Exception: CXMLDocument::LoadFromString()`, please check config file encoding, *must be UTF8 without BOM*.
+
+Let's try to invoke from test client. `PhotonWire.HubInvoker` is hub api testing tool. It exists at `$(SolutionDir)\packages\PhotonWire.1.0.0\tools\PhotonWire.HubInvoker\PhotonWire.HubInvoker.exe`.
+
+Configuration,
+
+ProcessPath | Argument | WorkingDirectory is same as Visual Studio's Debug Tab.
+DllPath is `/* Absolute Path */\PhotonLibs\GettingStarted.Server\bin\GettingStarted.Server.dll`
+
+Press Reload button, you can see like following image.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15644476/4e16f7ac-268e-11e6-9053-c6d29209ca49.png)
+
+
+
+At first, press Connect button to connect target server. And Invoke method, please try x = 100, y = 300 and press Send button.
+
+In visual studio, if set the breakpoint, you can step debugging and see, modify variables.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15644597/f39d935c-268e-11e6-970c-67c4e1a48400.png)
+
+and HubInvoker shows return value at log.
+
+```
+Connecting : 127.0.0.1:4530 GettingStarted
+Connect:True
++ MyFirstHub/Sum:400
+```
+There are basic steps of create server code.
+
+Getting Started - Unity Client
+---
+Download and Import `PhotonWire.UnityClient.unitypackage` from [release page](https://github.com/neuecc/PhotonWire/releases). If encounts `Unhandled Exception: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.`, Please change Build Settings -> Optimization -> Api Compatibility Level -> .NET 2.0.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15645273/70dbb1c0-2692-11e6-8716-9076fe3d81a1.png)
+
+PhotonWire's Unity Client needs additional SDK.
+
+* Download [Photon Server SDK](https://www.photonengine.com/en-US/OnPremise/Download) and pick `lib/Photon3Unity3D.dll` to `Assets\Plugins\Dll`.
+* Import [UniRx](https://github.com/neuecc/UniRx) from asset store.
+
+Add Unity Generated Projects to Solution.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15650356/e005cf7a-26b2-11e6-8b08-70569471ce13.png)
+
+> You can choose Unity generated solution based project or Standard solution based project. Benefit of Unity generated based is better integrated with Unity Editor(You can double click source code!) but solution path becomes strange.
+
+Search `Assets/Plugins/PhotonWire/PhotonWireProxy.tt` under `GettingStarted.UnityClient.CSharp.Plugins` and configure it, change the dll path and assemblyName. This file is typed client generator of server definition.
+
+```
+<#@ assembly name="$(SolutionDir)\GettingStarted.Server\bin\Debug\MsgPack.dll" #>
+<#@ assembly name="$(SolutionDir)\GettingStarted.Server\bin\Debug\GettingStarted.Server.dll" #>
+<#
+ // 1. ↑Change path to Photon Server Project's DLL and Server MsgPack(not client) DLL
+
+ // 2. Make Configuration -----------------------
+
+ var namespaceName = "GettingStarted.Client"; // namespace of generated code
+ var assemblyName = "GettingStarted.Server"; // Photon Server Project's assembly name
+ var baseHubName = "Hub`1"; // is `1, If you use base hub, change to like FooHub`1.
+ var useAsyncSuffix = true; // If true FooAsync
+
+ // If WPF, use "DispatcherScheduler.Current"
+ // If ConsoleApp, use "CurrentThreadScheduler.Instance"
+ // If Unity, use "Scheduler.MainThread"
+ var mainthreadSchedulerInstance = "Scheduler.MainThread";
+
+ // End of Configuration-----------------
+```
+
+Right click -> Run Custom Tool generates typed client(`PhotonWireProxy.Generated.cs`).
+
+![image](https://cloud.githubusercontent.com/assets/46207/15650491/ea1dfb44-26b3-11e6-982b-de44be2ab99c.png)
+
+Setup has been completed! Let's connect PhotonServer. Put uGUI Button to scene and attach following `PhotonButton` script.
+
+```csharp
+using ExitGames.Client.Photon;
+using PhotonWire.Client;
+using UniRx;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace GettingStarted.Client
+{
+ public class PhotonButton : MonoBehaviour
+ {
+ // set from inspector
+ public Button button;
+
+ ObservablePhotonPeer peer;
+ MyFirstHubProxy proxy;
+
+ void Start()
+ {
+ // Create Photon Connection
+ peer = new ObservablePhotonPeer(ConnectionProtocol.Tcp, peerName: "PhotonTest");
+
+ // Create typed server rpc proxy
+ proxy = peer.CreateTypedHub();
+
+ // Async Connect(return IObservable)
+ peer.ConnectAsync("127.0.0.1:4530", "GettingStarted.Server")
+ .Subscribe(x =>
+ {
+ UnityEngine.Debug.Log("IsConnected?" + x);
+ });
+
+
+ button.OnClickAsObservable().Subscribe(_ =>
+ {
+
+ // Invoke.Method calls server method and receive result.
+ proxy.Invoke.SumAsync(100, 300)
+ .Subscribe(x => Debug.Log("Server Return:" + x));
+
+ });
+ }
+
+ void OnDestroy()
+ {
+ // disconnect peer.
+ peer.Dispose();
+ }
+ }
+
+}
+```
+
+and press button, you can see `Server Return:400`.
+
+If shows Windows -> PhotonWire, you can see connection stae and graph of sent, received bytes.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15650771/fbdf81d4-26b5-11e6-87d0-811e1e77ca8f.png)
+
+Debugging both Server and Unity, I recommend use [SwitchStartupProject](https://visualstudiogallery.msdn.microsoft.com/f4e1be8c-b2dd-4dec-b273-dd88f8818571) extension.
+
+Create Photon + Unity multi startup.
+
+![image](https://cloud.githubusercontent.com/assets/46207/15650843/6a69a288-26b6-11e6-9aa6-ca520e47afd3.png)
+
+And debug it, top is server, bottom is unity.
+
+![bothdebug](https://cloud.githubusercontent.com/assets/46207/15651046/f0931f46-26b7-11e6-979c-b8a766511617.gif)
+
+Getting Started - .NET Client
+---
+.NET Client can use ASP.NET, ConsoleApplication, WPF, etc.
+
+* PM> Install-Package PhotonWire
+* Download [Photon Server SDK](https://www.photonengine.com/en-US/OnPremise/Download) and pick `lib/ExitGamesLibs.dll` and `lib/Photon3DotNet.dll`.
+
+Getting Started - Sharing Classes
+---
+PhotonWire supports complex type serialize by MsgPack. At first, share request/response type both server and client.
+
+Create .NET 3.5 Class Library Project - `GettingStarted.Share` and add the Person.cs.
+
+```csharp
+namespace GettingStarted.Share
+{
+ public class Person
+ {
+ public int Age { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ }
+}
+```
+
+Open project property window, Build Events -> Post-build event command line, add the following copy dll code.
+```
+xcopy "$(TargetDir)*.*" "$(SolutionDir)\GettingStarted.UnityClient\Assets\Plugins\Dll\" /Y /Q
+```
+
+Move to `GettingStareted.Server`, reference project `GettingStarted.Share` and add new method in MyFirstHub.
-PhotonServer.config -> Copyt to Output Directory, Copy always
+```csharp
+[Operation(1)]
+public Person CreatePerson(int seed)
+{
+ var rand = new Random(seed);
+ return new Person
+ {
+ FirstName = "Yoshifumi",
+ LastName = "Kawai",
+ Age = rand.Next(0, 100)
+ };
+}
+```
-Encount
-`Unhandled Exception: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.`
-Build Settings -> Optimization Api Compatibility Level -> .NET 2.0
+Maybe you encount error message, response type must be DataContract. You can modify quick fix.
+![image](https://cloud.githubusercontent.com/assets/46207/15651560/63aa7490-26bb-11e6-8b87-11f909eba119.png)
+
+And add the reference `System.Runtime.Serialization` to `GettingStarted.Share`.
+
+Build `GettingStarted.Server`, and Run Custom Tool of `PhotonWireProxy.tt`.
+
+```csharp
+// Unity Button Click
+proxy.Invoke.CreatePersonAsync(Random.Range(0, 100))
+ .Subscribe(x =>
+ {
+ UnityEngine.Debug.Log(x.FirstName + " " + x.LastName + " Age:" + x.Age);
+ });
+```
+
+Response deserialization is multi threaded and finally return to main thread by UniRx so deserialization does not affect performance. Furthermore deserializer is used pre-generated optimized serializer.
+
+```csharp
+[System.CodeDom.Compiler.GeneratedCodeAttribute("MsgPack.Serialization.CodeDomSerializers.CodeDomSerializerBuilder", "0.6.0.0")]
+[System.Diagnostics.DebuggerNonUserCodeAttribute()]
+public class GettingStarted_Share_PersonSerializer : MsgPack.Serialization.MessagePackSerializer {
+
+ private MsgPack.Serialization.MessagePackSerializer _serializer0;
+
+ private MsgPack.Serialization.MessagePackSerializer _serializer1;
+
+ public GettingStarted_Share_PersonSerializer(MsgPack.Serialization.SerializationContext context) :
+ base(context) {
+ MsgPack.Serialization.PolymorphismSchema schema0 = default(MsgPack.Serialization.PolymorphismSchema);
+ schema0 = null;
+ this._serializer0 = context.GetSerializer(schema0);
+ MsgPack.Serialization.PolymorphismSchema schema1 = default(MsgPack.Serialization.PolymorphismSchema);
+ schema1 = null;
+ this._serializer1 = context.GetSerializer(schema1);
+ }
+
+ protected override void PackToCore(MsgPack.Packer packer, GettingStarted.Share.Person objectTree) {
+ packer.PackArrayHeader(3);
+ this._serializer0.PackTo(packer, objectTree.Age);
+ this._serializer1.PackTo(packer, objectTree.FirstName);
+ this._serializer1.PackTo(packer, objectTree.LastName);
+ }
+
+ protected override GettingStarted.Share.Person UnpackFromCore(MsgPack.Unpacker unpacker) {
+ GettingStarted.Share.Person result = default(GettingStarted.Share.Person);
+ result = new GettingStarted.Share.Person();
+
+ int unpacked = default(int);
+ int itemsCount = default(int);
+ itemsCount = MsgPack.Serialization.UnpackHelpers.GetItemsCount(unpacker);
+ System.Nullable nullable = default(System.Nullable);
+ if ((unpacked < itemsCount)) {
+ nullable = MsgPack.Serialization.UnpackHelpers.UnpackNullableInt32Value(unpacker, typeof(GettingStarted.Share.Person), "Int32 Age");
+ }
+ if (nullable.HasValue) {
+ result.Age = nullable.Value;
+ }
+ unpacked = (unpacked + 1);
+ string nullable0 = default(string);
+ if ((unpacked < itemsCount)) {
+ nullable0 = MsgPack.Serialization.UnpackHelpers.UnpackStringValue(unpacker, typeof(GettingStarted.Share.Person), "System.String FirstName");
+ }
+ if (((nullable0 == null)
+ == false)) {
+ result.FirstName = nullable0;
+ }
+ unpacked = (unpacked + 1);
+ string nullable1 = default(string);
+ if ((unpacked < itemsCount)) {
+ nullable1 = MsgPack.Serialization.UnpackHelpers.UnpackStringValue(unpacker, typeof(GettingStarted.Share.Person), "System.String LastName");
+ }
+ if (((nullable1 == null)
+ == false)) {
+ result.LastName = nullable1;
+ }
+ unpacked = (unpacked + 1);
+
+ return result;
+ }
+}
+```
+
+Startup Configuration
+---
+Override the Startup methods, you can configure options.
+
+```csharp
+public class Startup : PhotonWireApplicationBase
+{
+ // When throw exception, returns exception information.
+ public override bool IsDebugMode
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ // connected peer is server to server?
+ protected override bool IsServerToServerPeer(InitRequest initRequest)
+ {
+ return (initRequest.ApplicationId == "MyMaster");
+ }
+
+ // initialize, if needs server to server connection, write here.
+ protected override void SetupCore()
+ {
+ var _ = ConnectToOutboundServerAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4530), "MyMaster");
+ }
+
+ // tear down
+ protected override void TearDownCore()
+ {
+ base.TearDownCore();
+ }
+}
+```
+
+More options, see [reference](https://github.com/neuecc/PhotonWire/wiki).
+
+Hub
+---
+Hub concept is highly inspired by [ASP.NET SignalR](http://www.asp.net/signalr/overview/getting-started) so SignalR's document is maybe useful.
+
+Hub supported typed client broadcast.
+
+```csharp
+// define client interface.
+public interface ITutorialClient
+{
+ [Operation(0)]
+ void GroupBroadcastMessage(string message);
+}
+
+// Hub
+[Hub(100)]
+public class Tutorial : PhotonWire.Server.Hub
+{
+ [Operation(2)]
+ public void BroadcastAll(string message)
+ {
+ // Get ClientProxy from Clients property, choose target and Invoke.
+ this.Clients.All.GroupBroadcastMessage(message);
+ }
+}
+```
+
+Hub have two instance property, [OperationContext](https://github.com/neuecc/PhotonWire/wiki/PhotonWire.Server#operationcontext) and [Clients](https://github.com/neuecc/PhotonWire/wiki/PhotonWire.Server#hubcallerclientproxyt). OperationContext is information per operation. It has `Items` - per operation storage(`IDictionary