/// <summary>
        /// Creates a Stormancer client instance.
        /// </summary>
        /// <param name="configuration">A configuration instance containing options for the client.</param>
        public Client(ClientConfiguration configuration)
        {
            this._pingInterval = configuration.PingInterval;
            this._scheduler    = configuration.Scheduler;
            DependencyResolver = new StormancerResolver();
            DependencyResolver.Register <ILogger>(() => configuration.Logger);
            DependencyResolver.Register(() => new ApiClient(configuration, DependencyResolver));
            DependencyResolver.Register <ITokenHandler>(() => new TokenHandler());
            DependencyResolver.RegisterComponent <IConnectionHandler>(new IConnectionHandler());
            DependencyResolver.RegisterComponent <IClock>(new IClock(this));

#if UNITY_EDITOR
            IConnectionHandler temp = DependencyResolver.Resolve <IConnectionHandler>();
            temp.PeerConnected += (PeerConnectedContext pcc) =>
            {
                ConnectionWrapper connection = new ConnectionWrapper(pcc.Connection, configuration.Plugins.OfType <EditorPlugin.StormancerEditorPlugin>().First());
                pcc.Connection = connection;
            };
#endif

            this.DependencyResolver.Register <ITransport>(configuration.TransportFactory);
            this._accountId       = configuration.Account;
            this._applicationName = configuration.Application;
            //TODO handle scheduler in the transport
            this._dispatcher  = configuration.Dispatcher;
            _requestProcessor = new Stormancer.Networking.Processors.RequestProcessor(Logger, Enumerable.Empty <IRequestModule>());

            _scenesDispatcher = new Processors.SceneDispatcher();
            this._dispatcher.AddProcessor(_requestProcessor);
            this._dispatcher.AddProcessor(_scenesDispatcher);
            this._metadata = configuration._metadata;

            foreach (var serializer in configuration.Serializers)
            {
                this._serializers.Add(serializer.Name, serializer);
            }

            this._maxPeers = configuration.MaxPeers;

            foreach (var plugin in configuration.Plugins)
            {
                plugin.Build(_pluginCtx);
            }

            var ev = _pluginCtx.ClientCreated;
            if (ev != null)
            {
                ev(this);
            }

            _transport = DependencyResolver.Resolve <ITransport>();
            this._metadata.Add("serializers", string.Join(",", this._serializers.Keys.ToArray()));
            this._metadata.Add("transport", _transport.Name);
            this._metadata.Add("version", "1.1.0");
            this._metadata.Add("platform", "Unity");
            this._metadata.Add("protocol", "2");

            Initialize();
        }
Esempio n. 2
0
        public Task <SceneEndpoint> GetSceneEndpoint <T>(string accountId, string applicationName, string sceneId, T userData)
        {
            var serializer = new MsgPackSerializer();

            byte[] data;
            using (var s = new MemoryStream())
            {
                serializer.Serialize(userData, s);
                data = s.ToArray();
            }
            var logger = _resolver.Resolve <ILogger>();

            logger.Log(Stormancer.Diagnostics.LogLevel.Trace, "Client", "creating endpoint request for remote server");

            return(SendWithRetry(() => CreateRequest(accountId, applicationName, sceneId, data, logger), 5000, 15000).ContinueWith(t =>
            {
                logger.Log(Stormancer.Diagnostics.LogLevel.Trace, "Client", "Received endpoint response from remote server");
                try
                {
                    var response = t.Result;

                    try
                    {
                        response.EnsureSuccessStatusCode();
                    }
                    catch (HTTPException exception)
                    {
                        logger.Log(Stormancer.Diagnostics.LogLevel.Error, "Client", "GetScene failed.");
                        if (exception.StatusCode == HttpStatusCode.NotFound)
                        {
                            logger.Log(Stormancer.Diagnostics.LogLevel.Error, "Client", "GetScene failed: Unable to get the scene. Please check you entered the correct account id, application name and scene id.");
                            throw new ArgumentException("Unable to get the scene {0}/{1}/{2}. Please check you entered the correct account id, application name and scene id.", exception);
                        }
                        throw;
                    }

                    logger.Log(Stormancer.Diagnostics.LogLevel.Trace, "Client", "Token succefully received");
                    return _resolver.Resolve <ITokenHandler>().DecodeToken(response.ReadAsString());
                }
                catch (Exception ex)
                {
                    UnityEngine.Debug.LogException(ex);
                    logger.Log(Stormancer.Diagnostics.LogLevel.Error, "Client", "GetScene failed: cannot retreive the connection token.");
                    throw new InvalidOperationException("An error occured while retrieving the connection token. See the inner exception for more informations.", ex);
                }
            }));
        }
Esempio n. 3
0
        /// <summary>
        /// Registers a route on the local peer.
        /// </summary>
        /// <param name="route">A string containing the name of the route to listen to.</param>
        /// <param name="handler">An action that is executed when the remote peer call the route.</param>
        /// <returns></returns>
        public void AddRoute(string route, Action <Packet <IScenePeer> > handler, Dictionary <string, string> metadata = null)
        {
            if (route[0] == '@')
            {
                DependencyResolver.Resolve <ILogger>().Log(Stormancer.Diagnostics.LogLevel.Error, this.Id, "AddRoute failed: Tried to create a route with the @ character");
                throw new ArgumentException("A route cannot start with the @ character.");
            }
            metadata = new Dictionary <string, string>();

            if (Connected)
            {
                DependencyResolver.Resolve <ILogger>().Error("AddRoute failed: Tried to create a route once connected");
                throw new InvalidOperationException("You cannot register handles once the scene is connected.");
            }

            Route routeObj;

            if (!_localRoutesMap.TryGetValue(route, out routeObj))
            {
                DependencyResolver.Resolve <ILogger>().Trace("Created route with id : '{0}'", route);
                routeObj = new Route(this, route, metadata);
                _localRoutesMap.Add(route, routeObj);
                var ev = _pluginCtx.RouteCreated;
                if (ev != null)
                {
                    ev(this, routeObj);
                }
            }

            OnMessage(route).Subscribe(handler);
        }