/// <inheritdoc /> public ClientPeerSession Create(IConnectionDetails connectionDetails, NetConnection connection) { if (connectionDetails == null) { throw new ArgumentNullException(nameof(connectionDetails)); } if (connection == null) { throw new ArgumentNullException(nameof(connection)); } //Build the message router service LidgrenNetworkMessageRouterService routerService = new LidgrenServerNetworkMessageRouterService(new LidgrenNetworkMessageFactory(), connection, Serializer); NetworkMessagePublisher basicMessagePublisher = new NetworkMessagePublisher(); DefaultNetworkMessageRouteBackService routebackService = new DefaultNetworkMessageRouteBackService(NetPeerAUIDService, PeerLogger); DefaultDisconnectionServiceHandler disconnectionHandler = new DefaultDisconnectionServiceHandler(); //TODO: Clean this up disconnectionHandler.DisconnectionEventHandler += () => PeerServiceCollection.Remove(connectionDetails.ConnectionID); //Try to create the incoming peer; consumers of the library may reject the connection. ClientPeerSession session = ManagedSessionFactory.CreateIncomingPeerSession(routerService, connectionDetails, basicMessagePublisher, disconnectionHandler, routebackService); if (session == null) { return(null); } if (session.PeerDetails.ConnectionID == 0) { throw new InvalidOperationException("Generated peer has an unset connection ID."); } //Create a service context for the server. ClientSessionServiceContext serviceContext = new ClientSessionServiceContext(routerService, basicMessagePublisher, session); //Enter AUID lock PeerServiceCollection.syncObj.EnterWriteLock(); try { PeerServiceCollection.Add(session.PeerDetails.ConnectionID, serviceContext); } finally { PeerServiceCollection.syncObj.ExitWriteLock(); } return(session); }
/// <summary> /// Called internally by Photon when a peer is attempting to connect. /// Services the connection attempt. /// </summary> /// <param name="initRequest">Request details.</param> /// <returns></returns> protected override PeerBase CreatePeer(InitRequest initRequest) { //Create the details so that the consumer of this class, who extends it, can indicate if this is a request we should service //AKA should a peer be made IConnectionDetails details = new PhotonServerIConnectionDetailsAdapter(initRequest.RemoteIP, initRequest.RemotePort, initRequest.LocalPort); //If we should service the peer if (ShouldServiceIncomingPeerConnect(details)) { //Unlike in PhotonServer we have the expectation that they WILL be creating a peer since they said they would //Because of this we'll be creating the actual PeerBase in advance. NetworkMessagePublisher publisher = new NetworkMessagePublisher(); IDisconnectionServiceHandler disconnectionHandler = new PhotonServerIDisconnectionServiceHandlerAdapter(); //Build the peer first since it's required for the network message sender GladNetClientPeer peerBase = new GladNetClientPeer(initRequest, publisher, Deserializer, disconnectionHandler); //We should make the ClientPeerSession now ClientPeerSession session = CreateClientSession(new PhotonServerINetworkMessageSenderClientAdapter(peerBase, Serializer), details, publisher, disconnectionHandler, routebackService); if (session == null) { peerBase.Disconnect(); return(null); } //Add the ID to the AUID map service and setup removal auidMapService.Add(details.ConnectionID, session); disconnectionHandler.DisconnectionEventHandler += () => auidMapService.Remove(details.ConnectionID); //This must be done to keep alive the reference of the session //Otherwise GC will clean it up (WARNING: This will create circular reference and cause a leak if you do not null the peer out eventually) peerBase.GladNetPeer = session; return(peerBase); } else { //Disconnect the client if they're not going to have a peer serviced initRequest.PhotonPeer.DisconnectClient(); return(null); } }