public void Initialize(PluginInitializationContext context) { string address = _communicator.GetProperty($"{_name}.Address") ?? (_communicator.PreferIPv6 ? "ff15::1" : "239.255.0.1"); int port = _communicator.GetPropertyAsInt($"{_name}.Port") ?? 4061; string intf = _communicator.GetProperty($"{_name}.Interface") ?? ""; string lookupEndpoints = _communicator.GetProperty($"{_name}.Lookup") ?? ""; if (lookupEndpoints.Length == 0) { int ipVersion = _communicator.PreferIPv6 ? Network.EnableIPv6 : Network.EnableIPv4; List <string> interfaces = Network.GetInterfacesForMulticast(intf, ipVersion); lookupEndpoints = string.Join(":", interfaces.Select( intf => $"udp -h \"{address}\" -p {port} --interface \"{intf}\"")); } if (_communicator.GetProperty($"{_name}.Reply.Endpoints") == null) { _communicator.SetProperty($"{_name}.Reply.Endpoints", intf.Length == 0 ? "udp -h *" : $"udp -h \"{intf}\""); } if (_communicator.GetProperty($"{_name}.Locator.Endpoints") == null) { _communicator.SetProperty($"{_name}.Locator.AdapterId", Guid.NewGuid().ToString()); } _replyAdapter = _communicator.CreateObjectAdapter(_name + ".Reply"); _locatorAdapter = _communicator.CreateObjectAdapter(_name + ".Locator"); // We don't want those adapters to be registered with the locator so clear their locator. _replyAdapter.Locator = null; _locatorAdapter.Locator = null; var lookupPrx = ILookupPrx.Parse($"IceLocatorDiscovery/Lookup -d:{lookupEndpoints}", _communicator); lookupPrx = lookupPrx.Clone(clearRouter: false); ILocatorPrx voidLocator = _locatorAdapter.AddWithUUID(new VoidLocator(), ILocatorPrx.Factory); var lookupReplyId = new Identity(Guid.NewGuid().ToString(), ""); ILookupReplyPrx?locatorReplyPrx = _replyAdapter.CreateProxy(lookupReplyId, ILookupReplyPrx.Factory).Clone( invocationMode: InvocationMode.Datagram); _defaultLocator = _communicator.DefaultLocator; string instanceName = _communicator.GetProperty($"{_name}.InstanceName") ?? ""; var locatorId = new Identity("Locator", instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString()); _locator = new Locator(_name, lookupPrx, _communicator, instanceName, voidLocator, locatorReplyPrx); _locatorPrx = _locatorAdapter.Add(locatorId, _locator, ILocatorPrx.Factory); _communicator.DefaultLocator = _locatorPrx; _replyAdapter.Add(lookupReplyId, new LookupReply(_locator)); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
internal override Connection CreateConnection( IConnectionManager manager, MultiStreamTransceiverWithUnderlyingTransceiver transceiver, IConnector?connector, string connectionId, ObjectAdapter?adapter) => new WSConnection(manager, this, transceiver, connector, connectionId, adapter);
private ObjectAdapter AddObjectAdapter(string?name = null, bool serializeDispatch = false, TaskScheduler?taskScheduler = null, IRouterPrx?router = null) { if (name != null && name.Length == 0) { throw new ArgumentException("the empty string is not a valid object adapter name", nameof(name)); } lock (this) { if (_isShutdown) { throw new CommunicatorDestroyedException(); } if (name != null) { if (_adapterNamesInUse.Contains(name)) { throw new ArgumentException($"an object adapter with name `{name}' is already registered", nameof(name)); } _adapterNamesInUse.Add(name); } } // Must be called outside the synchronization since the constructor can make client invocations // on the router if it's set. ObjectAdapter?adapter = null; try { adapter = new ObjectAdapter(this, name ?? "", serializeDispatch, taskScheduler, router); lock (this) { if (_isShutdown) { throw new CommunicatorDestroyedException(); } _adapters.Add(adapter); return(adapter); } } catch (Exception) { if (adapter != null) { adapter.Destroy(); } if (name != null) { lock (this) { _adapterNamesInUse.Remove(name); } } throw; } }
public Connection CreateConnection( ZeroC.Ice.Endpoint endpoint, IAcmMonitor?monitor, IConnector?connector, string connectionId, ObjectAdapter?adapter) => _transceiver.CreateConnection(endpoint, monitor, connector, connectionId, adapter);
internal override Connection CreateConnection( IConnectionManager manager, MultiStreamOverSingleStreamSocket socket, IConnector?connector, string connectionId, ObjectAdapter?adapter) => new WSConnection(manager, this, socket, connector, connectionId, adapter);
protected BinaryConnection(Endpoint endpoint, ObjectAdapter?adapter) { Endpoint = endpoint; IsIncoming = adapter != null; IncomingFrameSizeMax = adapter?.IncomingFrameSizeMax ?? Endpoint.Communicator.IncomingFrameSizeMax; LastActivity = Time.Elapsed; _mutex = new object(); }
protected IPConnection( IConnectionManager manager, Endpoint endpoint, ITransceiver transceiver, BinaryConnection connection, IConnector?connector, string connectionId, ObjectAdapter?adapter) : base(manager, endpoint, connection, connector, connectionId, adapter) => _transceiver = transceiver;
public Connection CreateConnection( Endpoint endpoint, IACMMonitor?monitor, IConnector?connector, ObjectAdapter?adapter) { Debug.Assert(endpoint.IsSecure); return(new TcpConnection(endpoint, monitor, this, connector, adapter)); }
public override async Task RunAsync(string[] args) { await using Communicator communicator = Initialize(ref args); communicator.SetProperty("TestAdapter.Endpoints", GetTestEndpoint(0)); ObjectAdapter?adapter = communicator.CreateObjectAdapter("TestAdapter"); adapter.Add("perf", new PerformanceI()); //adapter.activate(); // Don't activate OA to ensure collocation is used. AllTests.Run(this); }
protected internal WSConnection( IConnectionManager manager, Endpoint endpoint, IBinaryConnection connection, IConnector?connector, string connectionId, ObjectAdapter?adapter) : base(manager, endpoint, connection, connector, connectionId, adapter) { }
public Connection CreateConnection( IConnectionManager manager, Endpoint endpoint, IConnector?connector, string connectionId, ObjectAdapter?adapter) { Debug.Assert(endpoint.IsSecure); return(new TcpConnection(manager, endpoint, this, connector, connectionId, adapter)); }
public void SetRouterInfo(RouterInfo routerInfo) { Debug.Assert(routerInfo != null); ObjectAdapter? adapter = routerInfo.Adapter; IReadOnlyList <Endpoint> endpoints = routerInfo.GetClientEndpoints(); // Must be called outside the synchronization lock (this) { if (_destroyed) { throw new CommunicatorDestroyedException(); } // // Search for connections to the router's client proxy // endpoints, and update the object adapter for such // connections, so that callbacks from the router can be // received over such connections. // for (int i = 0; i < endpoints.Count; ++i) { Endpoint endpoint = endpoints[i]; // // Modify endpoints with overrides. // if (_communicator.OverrideTimeout != null) { endpoint = endpoint.NewTimeout(_communicator.OverrideTimeout.Value); } // // The ConnectionI object does not take the compression flag of // endpoints into account, but instead gets the information // about whether messages should be compressed or not from // other sources. In order to allow connection sharing for // endpoints that differ in the value of the compression flag // only, we always set the compression flag to false here in // this connection factory. // endpoint = endpoint.NewCompressionFlag(false); foreach (ICollection <Connection> connections in _connections.Values) { foreach (Connection connection in connections) { if (connection.Endpoint == endpoint) { connection.Adapter = adapter; } } } } } }
public void Start(string name, Communicator communicator, string[] args) { _adapter = communicator.CreateObjectAdapter($"Hello-{name}"); string identity = communicator.GetProperty("Hello.Identity") ?? throw new InvalidOperationException("property `Hello.Identity' was not set"); string programName = communicator.GetProperty("Ice.ProgramName") ?? throw new InvalidOperationException("property `Ice.ProgramName' was not set"); _adapter.Add(identity, new Hello(programName)); _adapter.ActivateAsync(); }
public override async Task RunAsync(string[] args) { await Communicator.ActivateAsync(); Communicator.SetProperty("TestAdapter.Endpoints", GetTestEndpoint(0)); ObjectAdapter?adapter = Communicator.CreateObjectAdapter("TestAdapter"); adapter.Add("perf", new PerformanceI()); // Don't activate OA to ensure collocation is used. await AllTests.RunAsync(this); }
public override Connection CreateConnection( IConnectionManager manager, ITransceiver transceiver, IConnector?connector, string connectionId, ObjectAdapter?adapter) => new WSConnection(manager, this, transceiver, Protocol == Protocol.Ice1 ? (BinaryConnection) new Ice1BinaryConnection(transceiver, this, adapter) : new SlicBinaryConnection(transceiver, this, adapter), connector, connectionId, adapter);
public override async Task RunAsync(string[] args) { await using Communicator communicator = Initialize(ref args); await communicator.ActivateAsync(); ObjectAdapter adapter1 = communicator.CreateObjectAdapterWithEndpoints("TestAdapter", GetTestEndpoint(0)); adapter1.Add("test", new TestIntf(TaskScheduler.Default)); var schedulerPair = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 5); ObjectAdapter?adapter2 = communicator.CreateObjectAdapterWithEndpoints( "TestAdapterExclusiveTS", GetTestEndpoint(1), taskScheduler: schedulerPair.ExclusiveScheduler); adapter2.Add("test", new TestIntf(schedulerPair.ExclusiveScheduler)); ObjectAdapter?adapter3 = communicator.CreateObjectAdapterWithEndpoints( "TestAdapteConcurrentTS", GetTestEndpoint(2), taskScheduler: schedulerPair.ConcurrentScheduler); adapter3.Add("test", new TestIntf(schedulerPair.ConcurrentScheduler)); // Setup 21 worker threads for the .NET thread pool (we setup the minimum to avoid delays from the // thread pool thread creation). Unlike the server we setup one additional thread for running the // allTests task in addition to the 20 concurrent threads which are needed for concurrency testing. // TODO: Why are worker threads used here and not completion port threads? The SocketAsyncEventArgs // Completed event handler is called from the worker thread and not the completion port thread. ThreadPool.SetMinThreads(21, 4); ThreadPool.SetMaxThreads(21, 4); try { await AllTests.Run(this, true); } catch (TestFailedException ex) { Output.WriteLine($"test failed: {ex.Reason}"); Assert(false); throw; } }
public override async Task RunAsync(string[] args) { await using Communicator communicator = Initialize(ref args); await communicator.ActivateAsync(); ObjectAdapter?adapter = communicator.CreateObjectAdapterWithEndpoints("TestAdapter", GetTestEndpoint(0)); adapter.Add("test", new TestIntf(TaskScheduler.Default)); await adapter.ActivateAsync(); var schedulerPair = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 5); ObjectAdapter?adapter2 = communicator.CreateObjectAdapterWithEndpoints( "TestAdapterExclusiveTS", GetTestEndpoint(1), taskScheduler: schedulerPair.ExclusiveScheduler); adapter2.Add("test", new TestIntf(schedulerPair.ExclusiveScheduler)); await adapter2.ActivateAsync(); ObjectAdapter?adapter3 = communicator.CreateObjectAdapterWithEndpoints( "TestAdapteConcurrentTS", GetTestEndpoint(2), taskScheduler: schedulerPair.ConcurrentScheduler); adapter3.Add("test", new TestIntf(schedulerPair.ConcurrentScheduler)); await adapter3.ActivateAsync(); // Setup 20 worker threads for the .NET thread pool (we setup the minimum to avoid delays from the // thread pool thread creation). // TODO: Why are worker threads used here and not completion port threads? The SocketAsyncEventArgs // Completed event handler is called from the worker thread and not the completion port thread. This // might require fixing once we use Async socket primitives. ThreadPool.SetMinThreads(20, 4); ThreadPool.SetMaxThreads(20, 4); ServerReady(); await communicator.WaitForShutdownAsync(); }
// All the reference here are routable references. internal IRequestHandler GetRequestHandler(Reference rf) { if (rf.IsCollocationOptimized) { ObjectAdapter?adapter = FindObjectAdapter(rf); if (adapter != null) { return(rf.SetRequestHandler(new CollocatedRequestHandler(rf, adapter))); } } bool connect = false; ConnectRequestHandler?handler; if (rf.IsConnectionCached) { lock (_handlers) { if (!_handlers.TryGetValue(rf, out handler)) { handler = new ConnectRequestHandler(rf); _handlers.Add(rf, handler); connect = true; } } } else { handler = new ConnectRequestHandler(rf); connect = true; } if (connect) { rf.GetConnection(handler); } return(rf.SetRequestHandler(handler.Connect(rf))); }
internal IRequestHandler GetRequestHandler(RoutableReference rf, IObjectPrx proxy) { if (rf.GetCollocationOptimized()) { ObjectAdapter?adapter = FindObjectAdapter(proxy); if (adapter != null) { return(proxy.IceSetRequestHandler(new CollocatedRequestHandler(rf, adapter))); } } bool connect = false; ConnectRequestHandler handler; if (rf.GetCacheConnection()) { lock (_handlers) { if (!_handlers.TryGetValue(rf, out handler)) { handler = new ConnectRequestHandler(rf, proxy); _handlers.Add(rf, handler); connect = true; } } } else { handler = new ConnectRequestHandler(rf, proxy); connect = true; } if (connect) { rf.GetConnection(handler); } return(proxy.IceSetRequestHandler(handler.Connect(proxy))); }
protected internal override Connection CreateConnection( MultiStreamOverSingleStreamSocket socket, object?label, ObjectAdapter?adapter) => new WSConnection(this, socket, label, adapter);
public int run() { try { // // Create an object adapter. Services probably should NOT share // this object adapter, as the endpoint(s) for this object adapter // will most likely need to be firewalled for security reasons. // ObjectAdapter?adapter = null; if (_communicator.GetProperty("IceBox.ServiceManager.Endpoints") != null) { adapter = _communicator.createObjectAdapter("IceBox.ServiceManager"); adapter.Add(this, new Identity("ServiceManager", _communicator.GetProperty("IceBox.InstanceName") ?? "IceBox")); } // // Parse the property set with the prefix "IceBox.Service.". These // properties should have the following format: // // IceBox.Service.Foo=<assembly>:Package.Foo [args] // // We parse the service properties specified in IceBox.LoadOrder // first, then the ones from remaining services. // string prefix = "IceBox.Service."; Dictionary <string, string> services = _communicator.GetProperties(forPrefix: prefix); if (services.Count == 0) { throw new InvalidOperationException("ServiceManager: configuration must include at least one IceBox service"); } string[] loadOrder = (_communicator.GetPropertyAsList("IceBox.LoadOrder") ?? Array.Empty <string>()).Where( s => s.Length > 0).ToArray(); List <StartServiceInfo> servicesInfo = new List <StartServiceInfo>(); foreach (var name in loadOrder) { string key = prefix + name; string?value; if (!services.TryGetValue(key, out value)) { throw new InvalidOperationException($"ServiceManager: no service definition for `{name}'"); } servicesInfo.Add(new StartServiceInfo(name, value, _argv)); services.Remove(key); } foreach (var entry in services) { servicesInfo.Add(new StartServiceInfo(entry.Key.Substring(prefix.Length), entry.Value, _argv)); } // // Check if some services are using the shared communicator in which // case we create the shared communicator now with a property set that // is the union of all the service properties (from services that use // the shared communicator). // if (_communicator.GetProperties(forPrefix: "IceBox.UseSharedCommunicator.").Count > 0) { Dictionary <string, string> properties = CreateServiceProperties("SharedCommunicator"); foreach (StartServiceInfo service in servicesInfo) { if ((_communicator.GetPropertyAsInt($"IceBox.UseSharedCommunicator.{service.Name}") ?? 0) <= 0) { continue; } // // Load the service properties using the shared communicator properties as the default properties. // properties.ParseIceArgs(ref service.Args); // // Parse <service>.* command line options (the Ice command line options // were parsed by the call to createProperties above). // properties.ParseArgs(ref service.Args, service.Name); } string facetNamePrefix = "IceBox.SharedCommunicator."; bool addFacets = ConfigureAdmin(properties, facetNamePrefix); _sharedCommunicator = new Communicator(properties); if (addFacets) { // Add all facets created on shared communicator to the IceBox communicator // but renamed <prefix>.<facet-name>, except for the Process facet which is // never added. foreach (var p in _sharedCommunicator.FindAllAdminFacets()) { if (!p.Key.Equals("Process")) { _communicator.AddAdminFacet(p.Value.servant, p.Value.disp, facetNamePrefix + p.Key); } } } } foreach (StartServiceInfo s in servicesInfo) { StartService(s.Name, s.EntryPoint, s.Args); } // // Start Admin (if enabled) and/or deprecated IceBox.ServiceManager OA // _communicator.AddAdminFacet <ServiceManager, ServiceManagerTraits>(this, "IceBox.ServiceManager"); _communicator.getAdmin(); if (adapter != null) { adapter.Activate(); } // // We may want to notify external scripts that the services // have started and that IceBox is "ready". // This is done by defining the property IceBox.PrintServicesReady=bundleName // // bundleName is whatever you choose to call this set of // services. It will be echoed back as "bundleName ready". // // This must be done after start() has been invoked on the // services. // string?bundleName = _communicator.GetProperty("IceBox.PrintServicesReady"); if (bundleName != null) { Console.Out.WriteLine(bundleName + " ready"); } _communicator.waitForShutdown(); } catch (CommunicatorDestroyedException) { // Expected if the communicator is shutdown } catch (ObjectAdapterDeactivatedException) { // Expected if the mmunicator is shutdown } catch (System.Exception ex) { _logger.error("ServiceManager: caught exception:\n" + ex.ToString()); return(1); } finally { // // Invoke stop() on the services. // stopAll(); } return(0); }
public void Initialize(PluginInitializationContext context) { const string defaultIPv4Endpoint = "udp -h 239.255.0.1 -p 4061"; const string defaultIPv6Endpoint = "udp -h \"ff15::1\" -p 4061"; string?lookupEndpoints = _communicator.GetProperty($"{_name}.Lookup"); if (lookupEndpoints == null) { List <string> endpoints = new (); List <string> ipv4Interfaces = Network.GetInterfacesForMulticast("0.0.0.0", Network.EnableIPv4); List <string> ipv6Interfaces = Network.GetInterfacesForMulticast("::0", Network.EnableIPv6); endpoints.AddRange(ipv4Interfaces.Select(i => $"{defaultIPv4Endpoint} --interface \"{i}\"")); endpoints.AddRange(ipv6Interfaces.Select(i => $"{defaultIPv6Endpoint} --interface \"{i}\"")); lookupEndpoints = string.Join(":", endpoints); } if (_communicator.GetProperty($"{_name}.Reply.Endpoints") == null) { _communicator.SetProperty($"{_name}.Reply.Endpoints", "udp -h \"::0\" -p 0"); } _communicator.SetProperty($"{_name}.Reply.ProxyOptions", "-d"); if (_communicator.GetProperty($"{_name}.Locator.Endpoints") == null) { _communicator.SetProperty($"{_name}.Locator.AdapterId", Guid.NewGuid().ToString()); } _replyAdapter = _communicator.CreateObjectAdapter(_name + ".Reply"); _locatorAdapter = _communicator.CreateObjectAdapter(_name + ".Locator"); // We don't want those adapters to be registered with the locator so clear their locator. _replyAdapter.Locator = null; _locatorAdapter.Locator = null; var lookupPrx = ILookupPrx.Parse($"IceLocatorDiscovery/Lookup -d:{lookupEndpoints}", _communicator); lookupPrx = lookupPrx.Clone(clearRouter: false); var lookupReplyId = new Identity(Guid.NewGuid().ToString(), ""); ILookupReplyPrx locatorReplyPrx = _replyAdapter.CreateProxy(lookupReplyId, ILookupReplyPrx.Factory); Debug.Assert(locatorReplyPrx.InvocationMode == InvocationMode.Datagram); _defaultLocator = _communicator.DefaultLocator; string instanceName = _communicator.GetProperty($"{_name}.InstanceName") ?? ""; var locatorId = new Identity("Locator", instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString()); _locatorServant = new Locator(_name, lookupPrx, _communicator, instanceName, locatorReplyPrx); _locator = _locatorAdapter.Add(locatorId, _locatorServant, ILocatorPrx.Factory); _communicator.DefaultLocator = _locator; _replyAdapter.Add(lookupReplyId, new LookupReply(_locatorServant)); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
public void StartServer(Current current, CancellationToken cancel) { foreach (Communicator?c in _communicators) { c.WaitForShutdownAsync().Wait(cancel); c.Dispose(); } _communicators.Clear(); // Simulate a server: create a new communicator and object adapter. The object adapter is started on a // system allocated port. The configuration used here contains the Ice.Locator configuration variable. // The new object adapter will register its endpoints with the locator and create references containing // the adapter id instead of the endpoints. Dictionary <string, string> properties = _helper.Communicator !.GetProperties(); properties["TestAdapter.AdapterId"] = "TestAdapter"; properties["TestAdapter.ReplicaGroupId"] = "ReplicatedAdapter"; properties["TestAdapter2.AdapterId"] = "TestAdapter2"; Communicator serverCommunicator = _helper.Initialize(properties); _communicators.Add(serverCommunicator); // Use fixed port to ensure that OA re-activation doesn't re-use previous port from // another OA(e.g.: TestAdapter2 is re-activated using port of TestAdapter). int nRetry = 10; while (--nRetry > 0) { ObjectAdapter?adapter = null; ObjectAdapter?adapter2 = null; try { serverCommunicator.SetProperty("TestAdapter.Endpoints", _helper.GetTestEndpoint(_nextPort++)); serverCommunicator.SetProperty("TestAdapter2.Endpoints", _helper.GetTestEndpoint(_nextPort++)); adapter = serverCommunicator.CreateObjectAdapter("TestAdapter"); adapter2 = serverCommunicator.CreateObjectAdapter("TestAdapter2"); var locator = ILocatorPrx.Parse(_helper.GetTestProxy("locator", 0), serverCommunicator); adapter.Locator = locator; adapter2.Locator = locator; var testI = new TestIntf(adapter, adapter2, _registry); _registry.AddObject(adapter.Add("test", testI, IObjectPrx.Factory)); _registry.AddObject(adapter.Add("test2", testI, IObjectPrx.Factory)); adapter.Add("test3", testI); adapter.Activate(); adapter2.Activate(); break; } catch (TransportException) { if (nRetry == 0) { throw; } // Retry, if OA creation fails with EADDRINUSE(this can occur when running with JS web // browser clients if the driver uses ports in the same range as this test, ICE-8148) adapter?.Dispose(); adapter2?.Dispose(); } } }
private void Connected(IRouterPrx router, ISessionPrx session) { // Remote invocation should be done without acquiring a mutex lock. Debug.Assert(router != null); Debug.Assert(_communicator != null); // We create the callback object adapter here because createObjectAdapter internally makes synchronous // RPCs to the router. We can't create the OA on-demand when the client calls ObjectAdapter() or // AddWithUUID() because they can be called from the GUI thread. if (_useCallbacks) { Debug.Assert(_adapter == null); _adapter = _communicator.CreateObjectAdapterWithRouter(router); _adapter.Activate(); } string category = router.GetCategoryForClient(); lock (_mutex) { _router = router; if (_destroy) { // Run destroyInternal in a thread because it makes remote invocations. var t = new Thread(new ThreadStart(DestroyInternal)); t.Start(); return; } // Cache the category. _category = category; // Assign the session after _destroy is checked. _session = session; _connected = true; } // When using Ice1, we need to figure out the router's acm/session timeout and configure the connection // accordingly. With Ice2, this is no longer necessary, the idle timeout is negotiated on connection // establishment. Connection connection = router.GetConnection(); if (router.Protocol == Protocol.Ice1) { TimeSpan idleTimeout = TimeSpan.Zero; try { idleTimeout = TimeSpan.FromSeconds(router.GetACMTimeout()); } catch (OperationNotExistException) { } if (idleTimeout == TimeSpan.Zero) { idleTimeout = TimeSpan.FromSeconds(router.GetSessionTimeout()); } if (idleTimeout != TimeSpan.Zero) { connection.IdleTimeout = idleTimeout; } } connection.Closed += (sender, args) => Destroy(); try { _callback.Connected(this); } catch (SessionNotExistException) { Destroy(); } }
private void Connected(IRouterPrx router, ISessionPrx session) { // Remote invocation should be done without acquiring a mutex lock. Debug.Assert(router != null); Debug.Assert(_communicator != null); Connection?conn = router.GetCachedConnection(); string category = router.GetCategoryForClient(); TimeSpan acmTimeout = TimeSpan.Zero; try { acmTimeout = TimeSpan.FromSeconds(router.GetACMTimeout()); } catch (OperationNotExistException) { } if (acmTimeout == TimeSpan.Zero) { acmTimeout = TimeSpan.FromSeconds(router.GetSessionTimeout()); } // We create the callback object adapter here because createObjectAdapter internally makes synchronous // RPCs to the router. We can't create the OA on-demand when the client calls ObjectAdapter() or // AddWithUUID() because they can be called from the GUI thread. if (_useCallbacks) { Debug.Assert(_adapter == null); _adapter = _communicator.CreateObjectAdapterWithRouter(router); _adapter.Activate(); } lock (_mutex) { _router = router; if (_destroy) { // Run destroyInternal in a thread because it makes remote invocations. var t = new Thread(new ThreadStart(DestroyInternal)); t.Start(); return; } // Cache the category. _category = category; // Assign the session after _destroy is checked. _session = session; _connected = true; if (acmTimeout != TimeSpan.Zero) { Connection?connection = _router.GetCachedConnection(); Debug.Assert(connection != null); connection.Acm = new Acm(acmTimeout, connection.Acm.Close, AcmHeartbeat.Always); connection.Closed += (sender, args) => Destroy(); } } try { _callback.Connected(this); } catch (SessionNotExistException) { Destroy(); } }
public void Initialize(PluginInitializationContext context) { bool ipv4 = _communicator.GetPropertyAsBool("Ice.IPv4") ?? true; bool preferIPv6 = _communicator.GetPropertyAsBool("Ice.PreferIPv6Address") ?? false; string address; if (ipv4 && !preferIPv6) { address = _communicator.GetProperty("IceDiscovery.Address") ?? "239.255.0.1"; } else { address = _communicator.GetProperty("IceDiscovery.Address") ?? "ff15::1"; } int port = _communicator.GetPropertyAsInt("IceDiscovery.Port") ?? 4061; string intf = _communicator.GetProperty("IceDiscovery.Interface") ?? ""; if (_communicator.GetProperty("IceDiscovery.Multicast.Endpoints") == null) { if (intf.Length > 0) { _communicator.SetProperty("IceDiscovery.Multicast.Endpoints", $"udp -h \"{address}\" -p {port} --interface \"{intf}\""); } else { _communicator.SetProperty("IceDiscovery.Multicast.Endpoints", $"udp -h \"{address}\" -p {port}"); } } string lookupEndpoints = _communicator.GetProperty("IceDiscovery.Lookup") ?? ""; if (lookupEndpoints.Length == 0) { int ipVersion = ipv4 && !preferIPv6 ? Network.EnableIPv4 : Network.EnableIPv6; List <string> interfaces = Network.GetInterfacesForMulticast(intf, ipVersion); foreach (string p in interfaces) { if (p != interfaces[0]) { lookupEndpoints += ":"; } lookupEndpoints += $"udp -h \"{address}\" -p {port} --interface \"{p}\""; } } if (_communicator.GetProperty("IceDiscovery.Reply.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Reply.Endpoints", intf.Length == 0 ? "udp -h *" : $"udp -h \"{intf}\""); } if (_communicator.GetProperty("IceDiscovery.Locator.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString()); } _multicastAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Multicast"); _replyAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Reply"); _locatorAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Locator"); // Setup locator registry. var locatorRegistry = new LocatorRegistry(); ILocatorRegistryPrx locatorRegistryPrx = _locatorAdapter.AddWithUUID(locatorRegistry, ILocatorRegistryPrx.Factory); ILookupPrx lookupPrx = ILookupPrx.Parse($"IceDiscovery/Lookup -d:{lookupEndpoints}", _communicator).Clone(clearRouter: true); // Add lookup Ice object var lookup = new Lookup(locatorRegistry, lookupPrx, _communicator, _replyAdapter); _multicastAdapter.Add("IceDiscovery/Lookup", lookup); // Setup locator on the communicator. _locator = _locatorAdapter.AddWithUUID(new Locator(lookup, locatorRegistryPrx), ILocatorPrx.Factory); _defaultLocator = _communicator.DefaultLocator; _communicator.DefaultLocator = _locator; _multicastAdapter.Activate(); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
internal ObjectAdapter CreateObjectAdapter(string name, IRouterPrx?router) { lock (this) { if (_isShutdown) { throw new CommunicatorDestroyedException(); } if (name.Length > 0) { if (_adapterNamesInUse.Contains(name)) { throw new System.ArgumentException($"An object adapter with name `{name}' is already registered", nameof(name)); } _adapterNamesInUse.Add(name); } } // // Must be called outside the synchronization since initialize can make client invocations // on the router if it's set. // ObjectAdapter?adapter = null; try { if (name.Length == 0) { string uuid = System.Guid.NewGuid().ToString(); adapter = new ObjectAdapter(this, uuid, null, true); } else { adapter = new ObjectAdapter(this, name, router, false); } lock (this) { if (_isShutdown) { throw new CommunicatorDestroyedException(); } _adapters.Add(adapter); } } catch (CommunicatorDestroyedException) { if (adapter != null) { adapter.Destroy(); } throw; } catch (System.Exception) { if (name.Length > 0) { lock (this) { _adapterNamesInUse.Remove(name); } } throw; } return(adapter); }
public void Initialize(PluginInitializationContext context) { const string defaultIPv4Endpoint = "udp -h 239.255.0.1 -p 4061"; const string defaultIPv6Endpoint = "udp -h \"ff15::1\" -p 4061"; if (_communicator.GetProperty("IceDiscovery.Multicast.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Multicast.Endpoints", $"{defaultIPv4Endpoint}:{defaultIPv6Endpoint}"); } string?lookupEndpoints = _communicator.GetProperty("IceDiscovery.Lookup"); if (lookupEndpoints == null) { List <string> endpoints = new (); List <string> ipv4Interfaces = Network.GetInterfacesForMulticast("0.0.0.0", Network.EnableIPv4); List <string> ipv6Interfaces = Network.GetInterfacesForMulticast("::0", Network.EnableIPv6); endpoints.AddRange(ipv4Interfaces.Select(i => $"{defaultIPv4Endpoint} --interface \"{i}\"")); endpoints.AddRange(ipv6Interfaces.Select(i => $"{defaultIPv6Endpoint} --interface \"{i}\"")); lookupEndpoints = string.Join(":", endpoints); } if (_communicator.GetProperty("IceDiscovery.Reply.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Reply.Endpoints", "udp -h \"::0\" -p 0"); } if (_communicator.GetProperty("IceDiscovery.Locator.Endpoints") == null) { _communicator.SetProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString()); } _multicastAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Multicast"); _replyAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Reply"); _locatorAdapter = _communicator.CreateObjectAdapter("IceDiscovery.Locator"); // Setup locator registry. var locatorRegistryServant = new LocatorRegistry(_communicator); ILocatorRegistryPrx locatorRegistry = _locatorAdapter.AddWithUUID(locatorRegistryServant, ILocatorRegistryPrx.Factory); ILookupPrx lookup = ILookupPrx.Parse($"IceDiscovery/Lookup -d:{lookupEndpoints}", _communicator).Clone(clearRouter: true); // Add lookup Ice object var lookupServant = new Lookup(locatorRegistryServant, _communicator); _multicastAdapter.Add("IceDiscovery/Lookup", lookupServant); // Setup locator on the communicator. _locator = _locatorAdapter.AddWithUUID(new Locator(locatorRegistry, lookup, _replyAdapter), ILocatorPrx.Factory); _defaultLocator = _communicator.DefaultLocator; _communicator.DefaultLocator = _locator; _multicastAdapter.Activate(); _replyAdapter.Activate(); _locatorAdapter.Activate(); }
protected MultiStreamOverSingleStreamSocket( Endpoint endpoint, ObjectAdapter?adapter, SingleStreamSocket socket) : base(endpoint, adapter) => Underlying = socket;
internal async Task <int> RunAsync() { try { // Create an object adapter. Services probably should NOT share this object adapter, as the endpoint(s) // for this object adapter will most likely need to be behind a firewall for security reasons. ObjectAdapter?adapter = null; if (_communicator.GetProperty("IceBox.ServiceManager.Endpoints") != null) { adapter = _communicator.CreateObjectAdapter("IceBox.ServiceManager"); string instanceName = _communicator.GetProperty("IceBox.InstanceName") ?? "IceBox"; adapter.Add(new Identity("ServiceManager", instanceName), this); } // Parse the property set with the prefix "IceBox.Service.". These properties should have the following // format: // // IceBox.Service.Foo=<assembly>:Package.Foo [args] // // We parse the service properties specified in IceBox.LoadOrder first, then the ones from remaining // services. string prefix = "IceBox.Service."; Dictionary <string, string> services = _communicator.GetProperties(forPrefix: prefix); if (services.Count == 0) { throw new InvalidConfigurationException( "IceBox.ServiceManager: configuration must include at least one IceBox service"); } string[] loadOrder = (_communicator.GetPropertyAsList("IceBox.LoadOrder") ?? Array.Empty <string>()).Where( s => s.Length > 0).ToArray(); var servicesInfo = new List <StartServiceInfo>(); foreach (string name in loadOrder) { string key = prefix + name; if (!services.TryGetValue(key, out string?value)) { throw new InvalidConfigurationException( $"IceBox.ServiceManager: no service definition for `{name}'"); } servicesInfo.Add(new StartServiceInfo(name, value, _argv)); services.Remove(key); } foreach (KeyValuePair <string, string> entry in services) { servicesInfo.Add(new StartServiceInfo(entry.Key.Substring(prefix.Length), entry.Value, _argv)); } // Check if some services are using the shared communicator in which case we create the shared // communicator now with a property set that is the union of all the service properties (from services // that use the shared communicator). if (_communicator.GetProperties(forPrefix: "IceBox.UseSharedCommunicator.").Count > 0) { Dictionary <string, string> properties = CreateServiceProperties("SharedCommunicator"); foreach (StartServiceInfo service in servicesInfo) { if (!(_communicator.GetPropertyAsBool($"IceBox.UseSharedCommunicator.{service.Name}") ?? false)) { continue; } // Load the service properties using the shared communicator properties as the default properties. properties.ParseIceArgs(ref service.Args); // Parse <service>.* command line options (the Ice command line options were parsed by the call // to createProperties above). properties.ParseArgs(ref service.Args, service.Name); } string facetNamePrefix = "IceBox.SharedCommunicator."; bool addFacets = ConfigureAdmin(properties, facetNamePrefix); _sharedCommunicator = new Communicator(properties); if (addFacets) { // Add all facets created on shared communicator to the IceBox communicator // but renamed <prefix>.<facet-name>, except for the Process facet which is // never added. foreach (KeyValuePair <string, IObject> p in _sharedCommunicator.FindAllAdminFacets()) { if (!p.Key.Equals("Process")) { _communicator.AddAdminFacet(facetNamePrefix + p.Key, p.Value); } } } } foreach (StartServiceInfo s in servicesInfo) { StartService(s.Name, s.EntryPoint, s.Args); } // Start Admin (if enabled) and/or deprecated IceBox.ServiceManager OA _communicator.AddAdminFacet("IceBox.ServiceManager", this); _communicator.GetAdmin(); if (adapter != null) { await adapter.ActivateAsync().ConfigureAwait(false); } // We may want to notify external scripts that the services have started and that IceBox is "ready". // This is done by defining the property IceBox.PrintServicesReady=bundleName, bundleName is whatever // you choose to call this set of services. It will be echoed back as "bundleName ready". // // This must be done after start() has been invoked on the services. if (_communicator.GetProperty("IceBox.PrintServicesReady") is string bundleName) { Console.Out.WriteLine($"{bundleName} ready"); } await _communicator.WaitForShutdownAsync().ConfigureAwait(false); } catch (ObjectDisposedException) { // Expected if the communicator or ObjectAdater are disposed } catch (Exception ex) { _logger.Error($"IceBox.ServiceManager: caught exception:\n{ex}"); return(1); } finally { StopAll(); } return(0); }