下面的內(nèi)容析校,是翻譯的部分官方說明映琳。
本地服務(wù)器
https://doc.photonengine.com/en-us/server/current/getting-started/onpremises-or-saas
官方論壇
基本概念
Game Logic
游戲邏輯定義了客戶機(jī)如何與服務(wù)器交互。它實(shí)現(xiàn)操作纽谒、事件和服務(wù)器自己做的任何事情证膨。
任何游戲邏輯都可以直接在c#框架上開發(fā)。它的入口點(diǎn)是application類鼓黔,在“Photon.Socketserver.dll”中定義央勒。
-
LoadBalancing Application
目錄:("{Server_SDK_path}/src-server/Loadbalancing")
適用于處理基于房間類型的游戲。 -
MMO Demo Application
適用于單個(gè)的大型世界澳化。該應(yīng)用程序?yàn)榭蛻舳颂幚砜蛻舳烁信d趣的東西崔步,并為items、properties缎谷、actor等提供類井濒。 -
Lite Application
輕量,一個(gè)簡單的例子慎陵,幫助掌握眼虱。
Operations
一個(gè)Operation相當(dāng)于一次遠(yuǎn)程調(diào)用,客戶端使用遠(yuǎn)程調(diào)用來完成他們要做的任何事席纽。
Operation和它們的所有參數(shù)捏悬,都在服務(wù)端根據(jù)需求進(jìn)行定義。
客戶端可以通過設(shè)置哈希表匹配的方式調(diào)用任意Operation润梯。
客戶端和服務(wù)端框架來負(fù)責(zé)數(shù)據(jù)的序列化过牙、反序列化、傳輸纺铭。
每個(gè)Operation會(huì)有一個(gè)結(jié)果(回執(zhí))寇钉,這是像客戶但提供請求數(shù)據(jù)的一種方法。也可以跳過這個(gè)步驟來節(jié)約流量舶赔。
Operation調(diào)用和回執(zhí)扫倡,操作結(jié)果是在客戶端和服務(wù)器之間,其他客戶端不會(huì)知道這些竟纳。
Events
Events是服務(wù)端發(fā)給客戶端的消息撵溃。每個(gè)事件都以字節(jié)碼輸入,并附帶著游戲更新锥累。
“LoadBalancing Application”在服務(wù)端定義了幾個(gè)Events缘挑,但是也完全可以在客戶端定制Events。
與Operation不同桶略,接收到的Events很可能導(dǎo)致其他客戶端的Operation調(diào)用语淘。
這意味著诲宇,Events可能隨時(shí)到來。
“LoadBalancing Application”服務(wù)端在某人加入或離開房間時(shí)發(fā)送事件惶翻。
RaiseEvent這個(gè)Operation使Events變得真正通用:任意客戶端可以創(chuàng)建新的Events姑蓝,通過把數(shù)據(jù)和應(yīng)用的代碼放在一個(gè)hashtable中,并把它發(fā)送维贺。游戲數(shù)據(jù)可以在不需要更改服務(wù)器的情況下發(fā)送它掂。
當(dāng)然,對(duì)于更復(fù)雜的服務(wù)器端Events響應(yīng)溯泣,可以定義自定義的Operations來檢查Events數(shù)據(jù),編譯榕茧,或創(chuàng)建其他的Events垃沦。(就是支持自定義)。
Connections and Timeouts
與普通UDP不同用押,Photon的可靠UDP協(xié)議在服務(wù)器和客戶端之間建立了連接:UDP包中的命令有序列號(hào)肢簿,如果它們是可靠的,則有一個(gè)標(biāo)志蜻拨。如果是池充,接收端必須確認(rèn)該命令《兴希可靠的命令在短時(shí)間間隔內(nèi)重復(fù)執(zhí)行收夸,直到收到確認(rèn)。如果它沒有到達(dá)血崭,連接將超時(shí)卧惜。
雙方都從各自的角度獨(dú)立地監(jiān)視這種連接。雙方都有自己的規(guī)則來決定對(duì)方是否還在夹纫。
如果檢測到超時(shí)咽瓷,連接的那一側(cè)將發(fā)生斷開。只要一方認(rèn)為另一方不再響應(yīng)舰讹,就不會(huì)向它發(fā)送任何消息茅姜。這就是超時(shí)斷開是單向的而不是同步的原因。
啟動(dòng)服務(wù)器
- 啟動(dòng)方式有兩種月匣,一種是通過啟動(dòng)參數(shù)啟動(dòng).exe文件钻洒,另一種是使用
PhotonControl.exe
。 - IP設(shè)置:Autodetect public 使服務(wù)器在啟動(dòng)時(shí)檢測公共internet IP桶错。
使用Local IP意味著只有在相同的本地網(wǎng)絡(luò)中的客戶機(jī)才能連接航唆。你需要使用一個(gè)Public IP,如果想玩家從互聯(lián)網(wǎng)連接加入游戲院刁。 - 按照教程啟動(dòng)糯钙。啟動(dòng)成功。啟動(dòng)測試exe連接成功。
Photon Plugins
- PPlg僅適用于企業(yè)云或自承載的Photon Server v4任岸。
- 在Photon4中再榄,Plugin作為擴(kuò)展游戲/房間行為的新方法被引入,取代了Photon3中通過繼承實(shí)現(xiàn)的功能享潜。
- Plugin API的設(shè)計(jì)接近核心流程(創(chuàng)建空間困鸥、加入、離開等)剑按。
- 保持高度的靈活性:允許在處理之前和之后掛鉤到核心流疾就。
- 減少中斷流的機(jī)會(huì):在客戶端和服務(wù)器上快速提供錯(cuò)誤。
- 允許使用無鎖代碼:插件實(shí)例每次不會(huì)得到一個(gè)以上的調(diào)用艺蝴,框架提供了一個(gè)HTTP客戶機(jī)和集成在底層光子消息傳遞體系結(jié)構(gòu)(fiber)中的定時(shí)器猬腰。
- 降低復(fù)雜性和增加易用性:參見“最小化插件”。
- 概念:要添加自定義服務(wù)器邏輯猜敢,需要將代碼注入預(yù)定義的Photon server hooks姑荷。目前Photon Server只支持由Room Events觸發(fā)的GameServer Events。
- 根據(jù)定義缩擂,PPlg具有唯一的名稱鼠冕,并實(shí)現(xiàn)這些事件回調(diào)。自定義插件被編譯成一個(gè)DLL文件稱為插件程序集胯盯。然后懈费,所需的文件被“deploy”到您的Photon Server或上傳到您的企業(yè)云。
- 配置的插件程序集在運(yùn)行時(shí)隨著每個(gè)房間的創(chuàng)建而動(dòng)態(tài)加載陨闹。然后根據(jù)工廠模式創(chuàng)建插件實(shí)例楞捂。
- 觸發(fā)插件創(chuàng)建的房間稱為“host”游戲。后者可以直接從插件中訪問趋厉,并且它們都具有相同的生命周期寨闹。
- Webhooks是Photon plugins的一個(gè)很好的例子。Webhooks 1.2的源代碼可以在plugins SDK中找到君账。我們鼓勵(lì)你深入研究繁堡。
Basic Flow
Photon hooking原理依賴于六部流程:
- 攔截hook調(diào)用
當(dāng)回調(diào)被觸發(fā)時(shí),主機(jī)將控制權(quán)轉(zhuǎn)移到插件乡数。- [可選]更改調(diào)用信息
在處理客戶端/服務(wù)器發(fā)送的請求之前椭蹄,訪問和修改它。- [可選]注入自定義代碼
在處理調(diào)用前與主機(jī)交互(例如發(fā)出HTTP請求净赴、查詢室/參與者绳矩、設(shè)置計(jì)時(shí)器等)。- hook過程調(diào)用
決定如何處理請求(查看"ICallInfo Processing Methods")玖翅。- [可選]注入自定義代碼
一旦處理完畢翼馆,客戶端/服務(wù)器發(fā)送的請求就可以“作為只讀”割以。然而,插件仍然可以與主機(jī)交互应媚,即使在處理之后严沥。- 返回
插件將控制權(quán)轉(zhuǎn)移給主機(jī)。
Getting Started
Minimal Plugin
- 推薦的制作插件的簡單方法是擴(kuò)展PluginBase類中姜,而不是直接實(shí)現(xiàn)所有IGamePlugin方法消玄。然后您可以重寫您需要的那些。
- 要獲得最小的插件實(shí)現(xiàn)丢胚,您只需要重寫PluginBase.name翩瓜。它標(biāo)識(shí)這是個(gè)插件。
"Default" should not be used as a plugin name.
namespace MyCompany.MyProject.HivePlugin
{
public class CustomPlugin : PluginBase
{
public override string Name
{
get
{
return "CustomPlugin"; // anything other than "Default"
}
}
}
}
The Factory
- 插件工廠類被期望作為插件程序集的一部分實(shí)現(xiàn)嗜桌。它負(fù)責(zé)為每個(gè)房間創(chuàng)建一個(gè)插件實(shí)例奥溺。為了簡單起見,在下面的代碼片段中骨宠,工廠默認(rèn)返回
CustomPlugin
實(shí)例,而不檢查客戶機(jī)請求的插件到底是哪個(gè)相满。 - 觸發(fā)插件實(shí)例化的room作為IPluginHost參數(shù)傳遞給IPluginFactory层亿。創(chuàng)建方法。相同的參數(shù)也應(yīng)傳遞給IGamePlugin.SetupInstance立美,以便在插件內(nèi)部保存對(duì)游戲的引用匿又。IPluginHost提供了對(duì)room數(shù)據(jù)和操作的訪問。
namespace MyCompany.MyProject.HivePlugin
{
public class PluginFactory : IPluginFactory
{
public IGamePlugin Create(
IPluginHost gameHost,
string pluginName, // name of plugin requested by client
Dictionary<string, string> config, // plugin settings
out string errorMsg)
{
var plugin = new CustomPlugin();
if (plugin.SetupInstance(gameHost, config, out errorMsg))
{
return plugin;
}
return null;
}
}
}
Configuration
企業(yè)云
- 根據(jù)教程可以修改和保存屬性鍵值建蹄;但是沒找到添加屬性鍵值的地方碌更。
內(nèi)部部署
修改文件"Photon.LoadBalancing.dll.config"。
<PluginSettings Enabled="true">
<Plugins>
<Plugin
Name="{pluginName}"
AssemblyName="{filename}.dll"
Type="{namespace}.{pluginfactory class name}"
/>
</Plugins>
</PluginSettings>
- 構(gòu)建所需的插件DLL及其依賴項(xiàng)和其他文件必須根據(jù)配置的插件名稱值放置在“deploy\plugins{pluginName}\bin\”文件夾中洞慎。
Plugin Factory
- 我們的插件模型使用工廠設(shè)計(jì)模式痛单。插件按需按名稱實(shí)例化。
- 一個(gè)Photon Plugins插件程序集可能包含多個(gè)插件類和一個(gè)活動(dòng)的"插件工廠"劲腿。工廠一個(gè)一般就夠了旭绒,插件可以多搞幾個(gè)。例:每個(gè)游戲類型(或模式或難度等)都可以有一個(gè)插件焦人。該工廠還可以用于服務(wù)多個(gè)插件版本挥吵。用例。
- 客戶端通過請求初始化插件
roomOptions.Plugins
創(chuàng)建房間花椭。roomOptions.Plugins
是string[]
類型的忽匈,它的第一個(gè)元素應(yīng)該是插件的名字,并且將會(huì)傳遞給工廠矿辽。
- 如果客戶端沒有發(fā)送任何東西丹允,服務(wù)器要么使用默認(rèn)值(當(dāng)沒有配置任何東西時(shí))郭厌,要么使用插件工廠在創(chuàng)建時(shí)返回的值,不管創(chuàng)建的是啥嫌松。
如果在
PluginFactory.Create
中返回的插件的名稱與客戶端請求的不匹配沪曙,那么插件將被卸載,客戶端create或join operation將失敗萎羔,出現(xiàn)PluginMismatch(32757)錯(cuò)誤液走。
另外,目前,roomOptions.Plugins最多應(yīng)該包含一個(gè)元素(插件名稱字符串)。如果發(fā)送了多個(gè)元素(roomOptions.Plugins.Length > 1)則將接收到一個(gè)PluginMismatch(32757)錯(cuò)誤贾陷,房間連接或創(chuàng)建將失敗缘眶。
- 在工廠中只需要使用這個(gè)名字來加載相應(yīng)的插件如下:
public class PluginFactory : IPluginFactory
{
public IGamePlugin Create(IPluginHost gameHost, string pluginName, Dictionary<string, string> config, out string errorMsg)
{
PluginBase plugin = new DefaultPlugin(); // default
switch(pluginName)
{
case "Default":
// name not allowed, throw error
break;
case "NameOfYourPlugin":
plugin = new NameOfYourPlugin();
break;
case "NameOfOtherPlugin":
plugin = new NameOfOtherPlugin();
break;
default:
//plugin = new DefaultPlugin();
break;
}
if (plugin.SetupInstance(gameHost, config, out errorMsg))
{
return plugin;
}
return null;
}
}
Plugin Callbacks
Photon Server有9個(gè)預(yù)定義的hooks。
您不需要在代碼中顯式地注冊這些hooks髓废。默認(rèn)情況下巷懈,任何插件類都可以攔截所有9個(gè)事件。然而慌洪,您應(yīng)該實(shí)現(xiàn)您需要的顶燕。我們建議擴(kuò)展PluginBase并覆蓋所需的回調(diào)。所有的核心事件回調(diào)都有一個(gè)特殊的
ICallInfo
規(guī)則冈爹。大部分的回調(diào)都是通過客戶端的操作直接觸發(fā)涌攻。客戶端的請求操作频伤,是由ICallInfo.Request
方法提供的恳谎。-
OnCreateGame(ICreateGameCallInfo info)
- 先決條件:客戶端調(diào)用了
OpCreateRoom
或OpJoinOrCreateRoom
或OpJoinRoom
,并且room在服務(wù)器中無法找到憋肖。 - 處理:
- 先決條件:客戶端調(diào)用了