/// <summary> /// Registers the broadcast sender that sends a message to several receivers. /// Returns Guid (it's like URI for an MBR object) assigned for this sender that can be used /// to delete this broadcast sender later. /// </summary> /// <param name="generalBroadcastSender">The broadcast sender which sends a message via "true" multicast channel.</param> public string Add(GeneralBroadcastSender generalBroadcastSender) { // just add it as it would be the usual receiver ReceiverInfo receiverInfo = new ReceiverInfo(); receiverInfo.GeneralBroadcastSender = generalBroadcastSender; receiverInfo.Local = false; string uri = Guid.NewGuid().ToString("N") + "/" + generalBroadcastSender.Court; receiverInfo.MbrUri = uri; // register it using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { this._cachedReceiversInfoArray = null; this._receivers[uri] = receiverInfo; } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Add", LogMessageType.BroadcastRecipientAdded, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, generalBroadcastSender.Court, generalBroadcastSender.ITransportContext.HostIdentifier, "The \"true\" multicast sender is added."); } return(uri); }
/// <summary> /// Removes all recipients and broadcast senders. /// </summary> public void Clear() { using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { this._cachedReceiversInfoArray = null; // collect all receivers to unregister the sponsor object[] receiverInfoItems = new object[this._receivers.Count]; this._receivers.Values.CopyTo(receiverInfoItems, 0); GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.UnregisterSponsor), receiverInfoItems, true); this._receivers.Clear(); } }
/// <summary> /// Removes the receiver or the broadcast sender associated with the specified uri. /// Returns false if there is no such receiver found in the list of receivers. /// </summary> /// <param name="uri">The uri of the receiver.</param> public bool Remove(string uri) { if (uri == null || uri.Length <= 0) { return(false); } using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { // check if it is in the list if (!this._receivers.ContainsKey(uri)) { return(false); } this._cachedReceiversInfoArray = null; ReceiverInfo receiverInfo = (ReceiverInfo)this._receivers[uri]; this._receivers.Remove(uri); // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Remove", LogMessageType.BroadcastRecipientRemoved, null, null, receiverInfo.DbgRemoteHost, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, uri, null, "The broadcast recipient or \"true\" broadcast sender is removed from the list of recipients."); } // Sponsor is being deleted in another thread; otherwise client disconnection // will cause dispatcher to be freezed for lengthy time out GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.DeleteSponsorFromTheObjectAndFireEvent), receiverInfo, false); } return(true); }
/// <summary> /// Registers the receiver and associate the provided object with it. /// Returns false if the receiver has already been registered. /// WARNING: does not check whether the receiver supports the required interface (via Reflection) /// because this check requires client's dll. /// </summary> /// <param name="obj">The receiver being registered.</param> /// <param name="tag">The object associated with the receiver. This object is accessible when receiver is being unregistered or during filtering.</param> /// <param name="remoteGenuineUri">The uri of the remote host provided by any of Genuine Channels.</param> /// <param name="transportContext">The transport context of the remote host.</param> /// <returns>False if the receiver has been already registered.</returns> public bool Add(MarshalByRefObject obj, object tag, string remoteGenuineUri, ITransportContext transportContext) { if (obj == null) { throw new ArgumentNullException("obj"); } BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; // check if it is in the list string uri = RemotingServices.GetObjectUri(obj); if (uri == null && !RemotingServices.IsObjectOutOfAppDomain(obj)) { // it was not marshalled RemotingServices.Marshal(obj); uri = RemotingServices.GetObjectUri(obj); } using (ReaderAutoLocker reader = new ReaderAutoLocker(this._readerWriterLock)) { if (this._receivers.ContainsKey(uri)) { return(false); } } // this check can not be performed because client's dll is required // // check on the interface // bool supportInterface = false; // foreach(Type interfaceType in obj.GetType().GetInterfaces()) // if (interfaceType == this._interfaceToSupport) // { // supportInterface = true; // break; // } // if (! supportInterface) // throw GenuineExceptions.Get_Broadcast_ObjectDoesNotSupportDestinationInterface(); // adds the object to the receiver list ReceiverInfo receiverInfo = new ReceiverInfo(); receiverInfo.MbrObject = obj; receiverInfo.MbrUri = uri; receiverInfo.Tag = tag; if (binaryLogWriter != null) { try { if (receiverInfo.MbrObject != null) { receiverInfo.DbgRemoteHost = GenuineUtility.FetchHostInformationFromMbr(receiverInfo.MbrObject); } } catch (Exception ex) { binaryLogWriter.WriteImplementationWarningEvent("Dispatcher.Add", LogMessageType.Error, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Can't get HostInformation from MbrObject."); } } ObjRef objRef = receiverInfo.MbrObject.CreateObjRef(typeof(MarshalByRefObject)); receiverInfo.Local = objRef.IsFromThisAppDomain(); // cache object's info to speed up sending thru Genuine Channels if (!receiverInfo.Local) { if (remoteGenuineUri != null) { receiverInfo.IClientChannelSink = new GenuineTcpClientTransportSink(remoteGenuineUri, transportContext); } else { // check whether the client sink has registered itself on this MBR receiverInfo.IClientChannelSink = ChannelServices.GetChannelSinkProperties(obj)["GC_TS"] as IClientChannelSink; if (receiverInfo.IClientChannelSink == null) { throw GenuineExceptions.Get_Broadcast_ClientSinkIsUnknown(); } } // object uri receiverInfo.SerializedObjRef = objRef; // // and shell's uri // string shellUri; // ITransportContext iTransportContext; // GenuineUtility.FetchChannelUriFromMbr(obj, out shellUri, out iTransportContext); // if (shellUri == null) // throw GenuineExceptions.Get_Send_NoSender(objRef.URI); // // receiverInfo.ReceiverUri = shellUri; } // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Add", LogMessageType.BroadcastRecipientAdded, null, null, receiverInfo.DbgRemoteHost, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, null, null, "The broadcast recipient is added."); } // register the sponsor to prevent unexpected reclaiming ILease lease = (ILease)RemotingServices.GetLifetimeService(obj); if (lease != null) { lease.Register(this.GlobalSponsor); } // and register it using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { this._cachedReceiversInfoArray = null; this._receivers[uri] = receiverInfo; } return(true); }
/// <summary> /// Removes the receiver or the broadcast sender associated with the specified uri. /// Returns false if there is no such receiver found in the list of receivers. /// </summary> /// <param name="uri">The uri of the receiver.</param> public bool Remove(string uri) { if (uri == null || uri.Length <= 0) return false; using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { // check if it is in the list if (! this._receivers.ContainsKey(uri)) return false; this._cachedReceiversInfoArray = null; ReceiverInfo receiverInfo = (ReceiverInfo) this._receivers[uri]; this._receivers.Remove(uri); // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if ( binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0 ) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Remove", LogMessageType.BroadcastRecipientRemoved, null, null, receiverInfo.DbgRemoteHost, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, uri, null, "The broadcast recipient or \"true\" broadcast sender is removed from the list of recipients."); } // Sponsor is being deleted in another thread; otherwise client disconnection // will cause dispatcher to be freezed for lengthy time out GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.DeleteSponsorFromTheObjectAndFireEvent), receiverInfo, false); } return true; }
/// <summary> /// Registers the broadcast sender that sends a message to several receivers. /// Returns Guid (it's like URI for an MBR object) assigned for this sender that can be used /// to delete this broadcast sender later. /// </summary> /// <param name="generalBroadcastSender">The broadcast sender which sends a message via "true" multicast channel.</param> public string Add(GeneralBroadcastSender generalBroadcastSender) { // just add it as it would be the usual receiver ReceiverInfo receiverInfo = new ReceiverInfo(); receiverInfo.GeneralBroadcastSender = generalBroadcastSender; receiverInfo.Local = false; string uri = Guid.NewGuid().ToString("N") + "/" + generalBroadcastSender.Court; receiverInfo.MbrUri = uri; // register it using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { this._cachedReceiversInfoArray = null; this._receivers[uri] = receiverInfo; } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if ( binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0 ) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Add", LogMessageType.BroadcastRecipientAdded, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, generalBroadcastSender.Court, generalBroadcastSender.ITransportContext.HostIdentifier, "The \"true\" multicast sender is added."); } return uri; }
/// <summary> /// Registers the receiver and associate the provided object with it. /// Returns false if the receiver has already been registered. /// WARNING: does not check whether the receiver supports the required interface (via Reflection) /// because this check requires client's dll. /// </summary> /// <param name="obj">The receiver being registered.</param> /// <param name="tag">The object associated with the receiver. This object is accessible when receiver is being unregistered or during filtering.</param> /// <param name="remoteGenuineUri">The uri of the remote host provided by any of Genuine Channels.</param> /// <param name="transportContext">The transport context of the remote host.</param> /// <returns>False if the receiver has been already registered.</returns> public bool Add(MarshalByRefObject obj, object tag, string remoteGenuineUri, ITransportContext transportContext) { if (obj == null) throw new ArgumentNullException("obj"); BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; // check if it is in the list string uri = RemotingServices.GetObjectUri(obj); if (uri == null && ! RemotingServices.IsObjectOutOfAppDomain(obj)) { // it was not marshalled RemotingServices.Marshal(obj); uri = RemotingServices.GetObjectUri(obj); } using (ReaderAutoLocker reader = new ReaderAutoLocker(this._readerWriterLock)) { if (this._receivers.ContainsKey(uri)) return false; } // this check can not be performed because client's dll is required // // check on the interface // bool supportInterface = false; // foreach(Type interfaceType in obj.GetType().GetInterfaces()) // if (interfaceType == this._interfaceToSupport) // { // supportInterface = true; // break; // } // if (! supportInterface) // throw GenuineExceptions.Get_Broadcast_ObjectDoesNotSupportDestinationInterface(); // adds the object to the receiver list ReceiverInfo receiverInfo = new ReceiverInfo(); receiverInfo.MbrObject = obj; receiverInfo.MbrUri = uri; receiverInfo.Tag = tag; if (binaryLogWriter != null) { try { if (receiverInfo.MbrObject != null) receiverInfo.DbgRemoteHost = GenuineUtility.FetchHostInformationFromMbr(receiverInfo.MbrObject); } catch(Exception ex) { binaryLogWriter.WriteImplementationWarningEvent("Dispatcher.Add", LogMessageType.Error, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Can't get HostInformation from MbrObject."); } } ObjRef objRef = receiverInfo.MbrObject.CreateObjRef(typeof(MarshalByRefObject)); receiverInfo.Local = objRef.IsFromThisAppDomain(); // cache object's info to speed up sending thru Genuine Channels if (! receiverInfo.Local) { if (remoteGenuineUri != null) { receiverInfo.IClientChannelSink = new GenuineTcpClientTransportSink(remoteGenuineUri, transportContext); } else { // check whether the client sink has registered itself on this MBR receiverInfo.IClientChannelSink = ChannelServices.GetChannelSinkProperties(obj)["GC_TS"] as IClientChannelSink; if (receiverInfo.IClientChannelSink == null) throw GenuineExceptions.Get_Broadcast_ClientSinkIsUnknown(); } // object uri receiverInfo.SerializedObjRef = objRef; // // and shell's uri // string shellUri; // ITransportContext iTransportContext; // GenuineUtility.FetchChannelUriFromMbr(obj, out shellUri, out iTransportContext); // if (shellUri == null) // throw GenuineExceptions.Get_Send_NoSender(objRef.URI); // // receiverInfo.ReceiverUri = shellUri; } // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0 ) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Add", LogMessageType.BroadcastRecipientAdded, null, null, receiverInfo.DbgRemoteHost, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, null, null, "The broadcast recipient is added."); } // register the sponsor to prevent unexpected reclaiming ILease lease = (ILease) RemotingServices.GetLifetimeService(obj); if (lease != null) lease.Register(this.GlobalSponsor); // and register it using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { this._cachedReceiversInfoArray = null; this._receivers[uri] = receiverInfo; } return true; }