Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / MsmqOutputSessionChannel.cs / 1 / MsmqOutputSessionChannel.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.IO; using System.ServiceModel; using System.Transactions; using System.Collections.Generic; using System.IdentityModel.Selectors; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; using SR=System.ServiceModel.SR; sealed class MsmqOutputSessionChannel : TransportOutputChannel, IOutputSessionChannel { MsmqQueue msmqQueue; List> buffers; Transaction associatedTx; IOutputSession session; MsmqChannelFactory factory; MessageEncoder encoder; SecurityTokenProviderContainer certificateTokenProvider; public MsmqOutputSessionChannel(MsmqChannelFactory factory, EndpointAddress to, Uri via, bool manualAddressing) : base(factory, to, via, manualAddressing, factory.MessageVersion) { this.factory = factory; this.encoder = this.factory.MessageEncoderFactory.CreateSessionEncoder(); this.buffers = new List >(); this.buffers.Add(EncodeSessionPreamble()); if (factory.IsMsmqX509SecurityConfigured) { this.certificateTokenProvider = factory.CreateX509TokenProvider(to, via); } this.session = new OutputSession(); } int CalcSessionGramSize() { long sessionGramSize = 0; for (int i = 0; i < this.buffers.Count; i++) { ArraySegment buffer = this.buffers[i]; sessionGramSize += buffer.Count; } if (sessionGramSize > int.MaxValue) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR.GetString(SR.MsmqSessionGramSizeMustBeInIntegerRange))); return (int)sessionGramSize; } void CopySessionGramToBuffer(byte[] sessionGramBuffer) { int sessionGramOffset = 0; for (int i = 0; i < this.buffers.Count; i++) { ArraySegment buffer = this.buffers[i]; Buffer.BlockCopy(buffer.Array, buffer.Offset, sessionGramBuffer, sessionGramOffset, buffer.Count); sessionGramOffset += buffer.Count; } } void ReturnSessionGramBuffers() { // Don't return that fancy/schmancy end buffer for (int i = 0; i < this.buffers.Count - 1; i++) { this.Factory.BufferManager.ReturnBuffer(this.buffers[i].Array); } } public IOutputSession Session { get { return this.session; } } void OnCloseCore(bool isAborting, TimeSpan timeout) { // Dump the messages into the queue as a big bag. // no MSMQ send if aborting // no MSMQ send if the channel has only a preamble (no actual messages sent) if (! isAborting && this.buffers.Count > 1) { lock (ThisLock) { VerifyTransaction(); buffers.Add(EncodeEndMarker()); } int size = CalcSessionGramSize(); using (MsmqOutputMessage msmqMessage = new MsmqOutputMessage (this.Factory, size, this.RemoteAddress)) { msmqMessage.ApplyCertificateIfNeeded(this.certificateTokenProvider, this.factory.MsmqTransportSecurity.MsmqAuthenticationMode, timeout); msmqMessage.Body.EnsureBufferLength(size); msmqMessage.Body.BufferLength = size; CopySessionGramToBuffer(msmqMessage.Body.Buffer); bool lockHeld = false; try { Msmq.EnterXPSendLock(out lockHeld, this.factory.MsmqTransportSecurity.MsmqProtectionLevel); this.msmqQueue.Send(msmqMessage, MsmqTransactionMode.CurrentOrSingle); MsmqDiagnostics.SessiongramSent(this.Session.Id, msmqMessage.MessageId, this.buffers.Count); } catch (MsmqException ex) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex.Normalized); } finally { if (lockHeld) { Msmq.LeaveXPSendLock(); } ReturnSessionGramBuffers(); } } } if (null != this.msmqQueue) this.msmqQueue.Dispose(); this.msmqQueue = null; if (certificateTokenProvider != null) { if (isAborting) certificateTokenProvider.Abort(); else certificateTokenProvider.Close(timeout); } } protected override void OnAbort() { this.OnCloseCore(true, TimeSpan.Zero); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { this.OnCloseCore(false, timeout); return new CompletedAsyncResult(callback, state); } protected override void OnEndClose(IAsyncResult result) { CompletedAsyncResult.End(result); } protected override void OnClose(TimeSpan timeout) { this.OnCloseCore(false, timeout); } void OnOpenCore(TimeSpan timeout) { if (null == Transaction.Current) throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.MsmqTransactionCurrentRequired))); this.associatedTx = Transaction.Current; this.associatedTx.EnlistVolatile(new TransactionEnlistment(this, this.associatedTx), EnlistmentOptions.None); this.msmqQueue = new MsmqQueue(this.Factory.AddressTranslator.UriToFormatName(this.RemoteAddress.Uri), UnsafeNativeMethods.MQ_SEND_ACCESS); if (certificateTokenProvider != null) { certificateTokenProvider.Open(timeout); } } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { OnOpenCore(timeout); return new CompletedAsyncResult(callback, state); } protected override void OnEndOpen(IAsyncResult result) { CompletedAsyncResult.End(result); } protected override void OnOpen(TimeSpan timeout) { OnOpenCore(timeout); } protected override IAsyncResult OnBeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state) { OnSend(message, timeout); return new CompletedAsyncResult(callback, state); } protected override void OnEndSend(IAsyncResult result) { CompletedAsyncResult.End(result); } protected override void OnSend(Message message, TimeSpan timeout) { lock(ThisLock) { ThrowIfDisposed(); VerifyTransaction(); // serialize the indigo message to byte array and save... this.buffers.Add(EncodeMessage(message)); } } void VerifyTransaction() { if (this.associatedTx != Transaction.Current) { this.Fault(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.MsmqSameTransactionExpected))); } if (TransactionStatus.Active != Transaction.Current.TransactionInformation.Status) { this.Fault(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.MsmqTransactionNotActive))); } } ArraySegment EncodeSessionPreamble() { EncodedVia encodedVia = new EncodedVia(this.Via.AbsoluteUri); EncodedContentType encodedContentType = EncodedContentType.Create(this.encoder.ContentType); int startSize = ClientSimplexEncoder.ModeBytes.Length + SessionEncoder.CalcStartSize(encodedVia, encodedContentType) + ClientSimplexEncoder.PreambleEndBytes.Length; byte[] startBytes = this.Factory.BufferManager.TakeBuffer(startSize); Buffer.BlockCopy(ClientSimplexEncoder.ModeBytes, 0, startBytes, 0, ClientSimplexEncoder.ModeBytes.Length); SessionEncoder.EncodeStart(startBytes, ClientSimplexEncoder.ModeBytes.Length, encodedVia, encodedContentType); Buffer.BlockCopy(ClientSimplexEncoder.PreambleEndBytes, 0, startBytes, startSize - ClientSimplexEncoder.PreambleEndBytes.Length, ClientSimplexEncoder.PreambleEndBytes.Length); return new ArraySegment (startBytes, 0, startSize); } ArraySegment EncodeEndMarker() { return new ArraySegment (SessionEncoder.EndBytes, 0, SessionEncoder.EndBytes.Length); } // Stick a message into a buffer ArraySegment EncodeMessage(Message message) { ArraySegment messageData = this.encoder.WriteMessage(message, int.MaxValue, this.Factory.BufferManager, SessionEncoder.MaxMessageFrameSize); return SessionEncoder.EncodeMessageFrame(messageData); } MsmqChannelFactory Factory { get { return this.factory; } } class OutputSession : IOutputSession { string id = "uuid:/session-gram/" + Guid.NewGuid(); public string Id { get { return this.id; } } } class TransactionEnlistment : IEnlistmentNotification { MsmqOutputSessionChannel channel; Transaction transaction; public TransactionEnlistment(MsmqOutputSessionChannel channel, Transaction transaction) { this.channel = channel; this.transaction = transaction; } public void Prepare(PreparingEnlistment preparingEnlistment) { // Abort if this happens before the channel is closed... if(this.channel.State != CommunicationState.Closed) { channel.Fault(); Exception e = DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MsmqSessionChannelsMustBeClosed))); preparingEnlistment.ForceRollback(e); } else preparingEnlistment.Prepared(); } public void Commit(Enlistment enlistment) { enlistment.Done(); } public void Rollback(Enlistment enlistment) { this.channel.Fault(); enlistment.Done(); } public void InDoubt(Enlistment enlistment) { enlistment.Done(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TrustManager.cs
- ToolStripArrowRenderEventArgs.cs
- SQLBinaryStorage.cs
- securitymgrsite.cs
- XpsDocumentEvent.cs
- HttpDebugHandler.cs
- EntityDataSourceStatementEditor.cs
- HttpModulesSection.cs
- ListViewCancelEventArgs.cs
- SqlSelectClauseBuilder.cs
- ResourceAssociationType.cs
- QilCloneVisitor.cs
- BooleanFunctions.cs
- Trace.cs
- AnonymousIdentificationSection.cs
- XmlNullResolver.cs
- MetadataAssemblyHelper.cs
- infer.cs
- PathStreamGeometryContext.cs
- BindingCompleteEventArgs.cs
- WebPartChrome.cs
- StrongNameUtility.cs
- InputScope.cs
- CqlQuery.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- MatrixTransform.cs
- ConfigurationStrings.cs
- XsltException.cs
- StaticExtensionConverter.cs
- AssemblyResourceLoader.cs
- HtmlFormParameterWriter.cs
- FixedSOMLineCollection.cs
- XmlCountingReader.cs
- MenuItem.cs
- DependencyPropertyConverter.cs
- ProxyFragment.cs
- ObjectAnimationBase.cs
- SqlDataSourceFilteringEventArgs.cs
- UnsupportedPolicyOptionsException.cs
- Int32AnimationBase.cs
- WebHeaderCollection.cs
- TransformConverter.cs
- PrintControllerWithStatusDialog.cs
- XmlSchemaComplexType.cs
- MulticastNotSupportedException.cs
- ObjectParameter.cs
- MessageQueueKey.cs
- ArgIterator.cs
- EncryptedKey.cs
- ConnectionManagementElementCollection.cs
- XmlTextReaderImplHelpers.cs
- XmlUTF8TextReader.cs
- FrameworkRichTextComposition.cs
- ReflectionHelper.cs
- JsonClassDataContract.cs
- SqlMultiplexer.cs
- DataAccessor.cs
- MutexSecurity.cs
- SpellCheck.cs
- FaultDescription.cs
- NoneExcludedImageIndexConverter.cs
- ValidationPropertyAttribute.cs
- isolationinterop.cs
- TrustLevel.cs
- DataGridViewComboBoxColumn.cs
- XmlAttributeCache.cs
- DrawingBrush.cs
- RectKeyFrameCollection.cs
- DataObjectCopyingEventArgs.cs
- DispatcherHooks.cs
- CompiledIdentityConstraint.cs
- Cloud.cs
- SafeFileHandle.cs
- TreeViewItem.cs
- CorePropertiesFilter.cs
- MSG.cs
- ChangeConflicts.cs
- DataGridViewComboBoxColumn.cs
- Crc32Helper.cs
- SymLanguageVendor.cs
- DataGridColumnCollection.cs
- ServiceHttpModule.cs
- TrackBarDesigner.cs
- _NTAuthentication.cs
- InputMethodStateChangeEventArgs.cs
- ItemCollectionEditor.cs
- Line.cs
- TraceHwndHost.cs
- ServicePointManager.cs
- SqlCommandSet.cs
- SessionState.cs
- CodeRemoveEventStatement.cs
- Stackframe.cs
- WindowsStatic.cs
- DataListCommandEventArgs.cs
- BoolExpr.cs
- SafeSerializationManager.cs
- GetPageCompletedEventArgs.cs
- PathHelper.cs
- HebrewCalendar.cs