Регистрация подчиненного сервера (логин) на главном сервере - Photon Server -CJR Gaming MMO Framework
Я следую учебному пособию Кристиана Ричардса по разработке MMO с использованием Photon Server. Для тех, кто не знает, что это такое, это, по сути, охватывает переписывание фотонной структуры с нуля с использованием архитектуры типа MMO. Я столкнулся с многочисленными проблемами, которые я нашел или обойти, или исправить, но эта ошибка меня озадачила. Я сталкиваюсь со следующей ошибкой после запуска сервера и загрузки моего прокси-сервера и сервера входа в систему. Сервер запускается нормально, выглядит нормально, но как только он пытается зарегистрировать подчиненный сервер, он выдает эту ошибку в моем журнале прокси.
Журнал прокси-сервера:
2015-07-22 14: 56: 10,892 [1] INFO Photon.SocketServer.ApplicationBase [(null)] Остановка приложения: AppId= Proxy
2015-07-22 14: 57: 01,913 [1] INFO Photon.SocketServer.ApplicationBase [(null)] - Запуск приложения: AppId= Proxy; AppPath = C: \ Photon \ deploy \ ComplexServer, Type = ComplexServer.ComplexProxyServer
2015-07-22 14: 57: 01,968 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание AverageCounter: Name = ''
2015-07-22 14: 57: 01,977 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name = ''
2015-07-22 14: 57: 01,986 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 01,993 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 02,001 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name = ''
2015-07-22 14: 57: 02,008 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 02,017 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name = ''
2015-07-22 14: 57: 02,026 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 02,035 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 02,043 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name = ''
2015-07-22 14: 57: 02,051 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 02,058 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name = ''
2015-07-22 14: 57: 02,066 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name = ''
2015-07-22 14: 57: 02,084 [13] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - ConnID = 2, IP 127.0.0.1 на порту 4520, тип = TCPListener
2015-07-22 14: 57: 02,108 [13] DEBUG Photon.SocketServer.Protocol [(null)] - проанализированное сообщение инициализации для Master приложения, версия клиента 3.0.5, протокол GpBinaryV2 версия 1.6
2015-07-22 14: 57: 02,120 [11] DEBUG MMO.Photon.Application.PhotonConnectionCollection [(null)] - Получен запрос инициализации 127.0.0.1:4520 - Photon.SocketServer.InitRequest.
2015-07-22 14:57:02,127 [11] DEBUG MMO.Photon.Application.PhotonApplication [(null)] - получен запрос инициализации от подчиненного сервера
2015-07-22 14:57:02,154 [11] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - ответ отправлен в ConnId 2 с SendResult Ok
2015-07-22 14: 57: 02,331 [7] ОШИБКА Photon.SocketServer.ApplicationBase [(null)] - System.NotImplementedException: метод или операция не реализованы. в MMO.Photon.Application.PhotonRequest.MMO.Framework.IMessage.get_Code() в c:\Programming\SoftwareDevelopment\C#\MMO\MMO.Photon\Application\PhotonRequest.cs: строка 48 в MMO.Photon.Server.PhotonServerHerler.HandleMessage(сообщение IMessage, одноранговый узел PhotonServerPeer) в c:\Programming\SoftwareDevelopment\C#\MMO\MMO.Photon\Server\PhotonServerHandlerList.cs: строка 140 в операции MMO.Photon.Server.PhotonServerPeer.OnOperaquRequest (операция Операция RequestPest) в c:\Programming\SoftwareDevelopment\C#\MMO\MMO.Photon\Server\PhotonServerPeer.cs: строка 36 в Photon.SocketServer.ServerToServer.ServerPeerBase.OnReceiveInternal(данные в байтах [], SendParameters sendParameters, Int32 rtt rtt rtt) numFailures) в h:\svncontent\photon-socketserver-sdk_3.4\src\Photon.SocketServer\ServerToServer\ServerPeerBase.cs: строка 196 в Photon.SocketServer.PeerBase.<>c__DisplayClass6.b \5 в (h) в hn photon-socketserver-sdk_3.4\src\Photon.SocketServer\PeerBase.cs: строка 706 в ExitGames.Concurrency.Core.DefaultExecutor.Execute(List`1 toExecute) в d:\dev\exitgames-libs\src\Core\Concurrency\Core\DefaultExecutor.cs: строка 21 в ExitGames.Concurrency.Fibers.PoolFiber.Flush(Object) в d:\dev\exitgames-libs\src\Core\Concurrency\Fibers\PoolFiber.cs: строка 216 в System.Threading.ExecutionContext.RunInternal(ExecutionContext executeContext, обратный вызов contextCallback, состояние объекта, логическое preserveSyncCtx) в System.
* Итак, как вы можете видеть, он правильно отправляет ответы / запросы инициализации на главный сервер и регистрируется, пока не попытается зарегистрировать субсервер. Из наблюдения Login.log ниже, а также из сравнения отметки времени на "регистрирующем подсервере" видно, что вышеприведенное исключение выдается почти через секунду после того, как сервер входа в систему пытается зарегистрировать подсервер.
2015-07-22 14: 56: 10,845 [1] INFO Photon.SocketServer.ApplicationBase [(null)] - Остановка приложения: AppId= Логин 2015-07-22 14:57:01,541 [12] DEBUG Photon.SocketServer.ServerToServer.TevenServerPeer [(null)] - OnOutboundConnectionEstablished: отправка запроса на инициацию 2015-07-22 14:57:01,541 [1] DEBUG MMO.Photon.Application.PhotonApplication [(null)] - подключение к мастеру на 127.0.0.1:4520 2015-07-22 14:57:01,584 [1] INFO Photon.SocketServer.ApplicationBase [(null)] - Запуск приложения: AppId=Login; AppPath=C:\Photon\deploy\ComplexServer, Type=LoginServer.LoginServer 2015-07-22 14:57:01,592 [12] ОТЛАДКА Photon.SocketServer.ServerToServer.TevenServerPeer [(null)] - SentInitRequest: ConnID=2, канал =0, результат = ОК размер =41 байт 2015-07-22 14:57:02,157 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание AverageCounter: Name='' 2015-07-22 14:57:02,163 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name='' 2015-07-22 14:57:02,167 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,171 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,175 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name='' 2015-07-22 14:57:02,178 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,182 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name='' 2015-07-22 14:57:02,185 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null))] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,188 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,191 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name='' 2015-07-22 14:57:02,195 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,198 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание CountsPerSecondCounter: Name='' 2015-07-22 14:57:02,202 [13] DEBUG ExitGames.Diagnostics.Counter.CounterBase [(null)] - Создание NumericCounter: Name='' 2015-07-22 14:57:02,219 [15] DEBUG MMO.Photon.Application.PhotonApplication [(null)] - Получен запрос инициализации с суб-сервера 2015-07-22 14:57:02,314 [15] ОТЛАДКА Photon.SocketServer.ServerToServer.ServerPeerBase [(null)] - SentOpRequest: ConnID=2, opCode=0, ChannelId=0, результат =Ok, размер =439 байт 2015-07-22 14:57:02,318 [15] DEBUG MMO.Photon.Application.PhotonApplication [(null)] - регистрация подчиненного сервера
Следующий код взят из того, что я считаю соответствующими классами.
Класс PhotonRequest:
class PhotonRequest : IMessage
{
private readonly byte _code;
private readonly Dictionary<byte, object> _parameters;
private readonly int? _subCode;
public PhotonRequest(byte code, int? subCode, Dictionary<byte, object> parameters)
{
_code = code;
_parameters = parameters;
_subCode = subCode;
}
public short Code
{
get { return _code; }
}
public MessageType Type
{
get { return MessageType.Response; }
}
public int? SubCode
{
get { return _subCode; }
}
public Dictionary<byte, object> Parameters
{
get { return _parameters; }
}
byte IMessage.Code
{
get { throw new NotImplementedException(); }
}
}
Класс PhotonServerHandlerList:
public class PhotonServerHandlerList
{
private readonly DefaultRequestHandler _defaultRequestHandler;
private readonly DefaultResponseHandler _defaultResponseHandler;
private DefaultEventHandler _defaultEventHandler;
protected readonly ILogger Log;
private readonly Dictionary<int, PhotonServerHandler> _requestHandlerList;
private readonly Dictionary<int, PhotonServerHandler> _responseHandlerList;
private readonly Dictionary<int, PhotonServerHandler> _eventHandlerList;
public PhotonServerHandlerList(IEnumerable<IHandler<PhotonServerPeer>> handlers,
DefaultRequestHandler defaultRequestHandler, DefaultResponseHandler defaultResponseHandler,
DefaultEventHandler defaultEventHandler, PhotonApplication application)
{
_defaultRequestHandler = defaultRequestHandler;
_defaultResponseHandler = defaultResponseHandler;
_defaultEventHandler = defaultEventHandler;
Log = application.Log;
_requestHandlerList = new Dictionary<int, PhotonServerHandler>();
_responseHandlerList = new Dictionary<int, PhotonServerHandler>();
_eventHandlerList = new Dictionary<int, PhotonServerHandler>();
foreach (PhotonServerHandler handler in handlers)
{
if(!RegisterHandler(handler))
{
Log.WarnFormat("attempted to register handler {0} for type{1}|{2}", handler.GetType().Name, handler.Type, handler.Code);
}
}
}
public bool RegisterHandler(PhotonServerHandler handler)
{
var registered = false;
if((handler.Type & MessageType.Request) == MessageType.Request)
{
if (handler.SubCode.HasValue && !_requestHandlerList.ContainsKey(handler.SubCode.Value))
{
_requestHandlerList.Add(handler.SubCode.Value, handler);
registered = true;
}
else if (!_requestHandlerList.ContainsKey(handler.Code))
{
_requestHandlerList.Add(handler.Code, handler);
registered = true;
}
else
{
Log.ErrorFormat("RequestHandler list already contains handler for {0} - cannot add {1}", handler.Code, handler.GetType().Name);
}
}
if ((handler.Type & MessageType.Response) == MessageType.Response)
{
if (handler.SubCode.HasValue && !_responseHandlerList.ContainsKey(handler.SubCode.Value))
{
_responseHandlerList.Add(handler.SubCode.Value, handler);
registered = true;
}
else if (!_responseHandlerList.ContainsKey(handler.Code))
{
_responseHandlerList.Add(handler.Code, handler);
registered = true;
}
else
{
Log.ErrorFormat("Response Handler list already contains handler for {0} - cannot add {1}", handler.Code, handler.GetType().Name);
}
}
if ((handler.Type & MessageType.Async) == MessageType.Async)
{
if (handler.SubCode.HasValue && !_eventHandlerList.ContainsKey(handler.SubCode.Value))
{
_eventHandlerList.Add(handler.SubCode.Value, handler);
registered = true;
}
else if (!_eventHandlerList.ContainsKey(handler.Code))
{
_eventHandlerList.Add(handler.Code, handler);
registered = true;
}
else
{
Log.ErrorFormat("event Handler list already contains handler for {0} - cannot add {1}", handler.Code, handler.GetType().Name);
}
}
return registered;
}
public bool HandleMessage(IMessage message, PhotonServerPeer peer)
{
bool handled = false;
switch (message.Type)
{
case MessageType.Request:
if (message.SubCode.HasValue && _requestHandlerList.ContainsKey(message.SubCode.Value))
{
_requestHandlerList[message.SubCode.Value].HandleMessage(message, peer);
handled = true;
}
else if (!message.SubCode.HasValue && _requestHandlerList.ContainsKey(message.Code))
{
_requestHandlerList[message.Code].HandleMessage(message, peer);
handled = true;
}
else
{
_defaultRequestHandler.HandleMessage(message, peer);
}
break;
case MessageType.Response:
if (message.SubCode.HasValue && _responseHandlerList.ContainsKey(message.SubCode.Value))
{
_responseHandlerList[message.SubCode.Value].HandleMessage(message, peer);
handled = true;
}
else if (!message.SubCode.HasValue && _responseHandlerList.ContainsKey(message.Code))
{
_responseHandlerList[message.Code].HandleMessage(message, peer);
handled = true;
}
else
{
_defaultResponseHandler.HandleMessage(message, peer);
}
break;
case MessageType.Async:
if (message.SubCode.HasValue && _eventHandlerList.ContainsKey(message.SubCode.Value))
{
_eventHandlerList[message.SubCode.Value].HandleMessage(message, peer);
handled = true;
}
else if (!message.SubCode.HasValue && _eventHandlerList.ContainsKey(message.Code))
{
_eventHandlerList[message.Code].HandleMessage(message, peer);
handled = true;
}
else
{
_defaultEventHandler.HandleMessage(message, peer);
}
break;
}
return handled;
}
}
Интерфейс IMessage:
public interface IMessage
{
MessageType Type { get; }
byte Code { get; }
int? SubCode { get; } // nullable int
Dictionary<byte, object> Parameters { get; }
}
1 ответ
Хотя я не знаком с тем, что вы делаете, для меня это выделяется в этой стене текста отладки:
System.NotImplementedException: метод или операция не реализованы. в MMO.Photon.Application.PhotonRequest.MMO.Framework.IMessage.get_Code() в c:\Programming\SoftwareDevelopment\C#\MMO\MMO.Photon\Application\PhotonRequest.cs: строка 48
Ваш PhotonRequest
класс наследует IMessage
интерфейс, который является обязательным для его реализации, как это предписано интерфейсом. Вы в настоящее время заявляете Code
как следует в вашем классе:
public short Code
{
get
{
return _code;
}
}
Принимая во внимание, что это заявлено в IMessage
интерфейс как:
byte Code { get; }
Вам нужно изменить тип вашего на byte
вместо short
, Я не уверен, как это построено для вас (так как компилятор Visual Studio C# будет вызывать ошибку компилятора на этом), но это будет так.