/// <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(); }
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); } })); }
/// <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); }