将子服务器(登录)注册到主服务器 - Photon Server -CJR游戏MMO框架

时间:2015-07-22 19:53:10

标签: c# server mmo photon

我正在使用Photon Server关注有关MMO开发的Christian Richards教程。对于那些不知道它是什么的人来说,它基本上涵盖了使用MMO类型架构从头开始重写光子框架。我遇到了很多问题,我找到了解决方法或修复了,但这个错误让我感到难过。服务器启动后我遇到以下错误并加载我的代理服务器和登录服务器。服务器启动正常,查找它很好,但一旦它尝试注册子服务器,它会在我的代理日志中抛出此错误。

代理服务器日志:

2015-07-22 14:56:10,892 [1] INFO Photon.SocketServer.ApplicationBase [(null)]应用程序停止:AppId =代理

2015-07-22 14:57:01,913 [1] INFO Photon.SocketServer.ApplicationBase [(null)] - 应用程序启动:AppId =代理; 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,端口4520上的IP 127.0.0.1,type = 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 - 使用SendResult发送到ConnId 2的响应确定

2015-07-22 14:57:02,331 [7] ERROR Photon.SocketServer.ApplicationBase [(null)] - System.NotImplementedException:未实现方法或操作。    在c:\ Programming \ SoftwareDevelopment \ C#\ MMO \ MMO.Photon \ Application \ PhotonRequest.cs中的MMO.Photon.Application.PhotonRequest.MMO.Framework.IMessage.get_Code():第48行    在MMO.Photon.Server.PhotonServerHandlerList.HandleMessage(IMessage消息,PhotonServerPeer peer)中的c:\ Programming \ SoftwareDevelopment \ C#\ MMO \ MMO.Photon \ Server \ PhotonServerHandlerList.cs:第140行    在MMO.Photon.Server.PhotonServerPeer.OnOperationRequest(OperationRequest operationRequest,SendParameters sendParameters)中的c:\ Programming \ SoftwareDevelopment \ C#\ MMO \ MMO.Photon \ Server \ PhotonServerPeer.cs:第36行    at Photon.SocketServer.ServerToServer.ServerPeerBase.OnReceiveInternal(Byte [] data,SendParameters sendParameters,Int32 rtt,Int32 rttVariance,Int32 numFailures)在h:\ svncontent \ photon-socketserver-sdk_3.4 \ src \ Photon.SocketServer \ ServerToServer \ ServerPeerBase.cs:第196行    at Photon.SocketServer.PeerBase。<> c__DisplayClass6.b__5()in h:\ svncontent \ photon-socketserver-sdk_3.4 \ src \ Photon.SocketServer \ PeerBase.cs:line 706    在D:\ dev \ exitgames-libs \ src \ Core \ Concurrency \ Core \ DefaultExecutor.cs中的ExitGames.Concurrency.Core.DefaultExecutor.Execute(List`1 toExecute):第21行    在D:\ dev \ exitgames-libs \ src \ Core \ Concurrency \ Fibers \ PoolFiber.cs中的ExitGames.Concurrency.Fibers.PoolFiber.Flush(Object):第216行    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)    在System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()    在System.Threading.ThreadPoolWorkQueue.Dispatch()

*正如您所看到的,它将init响应/请求正确地发送到主服务器并登录,直到它尝试注册子服务器。通过观察下面的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.TemporaryServerPeer [(null)] - OnOutboundConnectionEstablished:发送init请求 2015-07-22 14:57:01,541 [1] DEBUG MMO.Photon.Application.PhotonApplication [(null)] - 在127.0.0.1:4520连接到master 2015-07-22 14:57:01,584 [1] INFO Photon.SocketServer.ApplicationBase [(null)] - 应用程序启动:AppId =登录; AppPath = C:\ Photon \ deploy \ ComplexServer,Type = LoginServer.LoginServer 2015-07-22 14:57:01,592 [12] DEBUG Photon.SocketServer.ServerToServer.TemporaryServerPeer [(null)] - SentInitRequest:ConnID = 2,ChannelId = 0,result = Ok size = 41 bytes 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)] - 从子服务器收到的init请求 2015-07-22 14:57:02,314 [15] DEBUG Photon.SocketServer.ServerToServer.ServerPeerBase [(null)] - SentOpRequest:ConnID = 2,opCode = 0,ChannelId = 0 result = Ok size = 439 bytes 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 个答案:

答案 0 :(得分:1)

虽然我不熟悉你在做什么,但这在调试文本的墙上突出了我:

  

System.NotImplementedException:方法或操作不是   实现。在   MMO.Photon.Application.PhotonRequest.MMO.Framework.IMessage.get_Code()   在   C:\程序\ SoftwareDevelopment \ C#\ MMO \ MMO.Photon \应用\ PhotonRequest.cs:行   48

您的PhotonRequest类继承了IMessage接口,这是接口规定的实现它的义务。您目前在班级中声明Code如下:

public short Code
{
    get
    {
        return _code;
    }
}

它在IMessage接口中声明为:

byte Code { get; }

您需要将您的类型更改为byte而不是short。我不确定这是如何构建的(因为Visual Studio C#编译器会在此处引发编译器错误),但就是这样。