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
- NativeMethodsOther.cs
- Vector3DIndependentAnimationStorage.cs
- AnimationLayer.cs
- HyperLinkStyle.cs
- DocumentAutomationPeer.cs
- RuleSettings.cs
- BamlLocalizabilityResolver.cs
- HtmlInputReset.cs
- ExtentJoinTreeNode.cs
- Marshal.cs
- StylusPointDescription.cs
- RadioButtonStandardAdapter.cs
- MeasurementDCInfo.cs
- XPathArrayIterator.cs
- ThumbAutomationPeer.cs
- RelativeSource.cs
- IncrementalHitTester.cs
- SettingsPropertyValueCollection.cs
- TogglePatternIdentifiers.cs
- WebBrowserContainer.cs
- SqlRewriteScalarSubqueries.cs
- RouteParameter.cs
- ActiveXSite.cs
- Transform.cs
- ObjectFullSpanRewriter.cs
- ModulesEntry.cs
- SurrogateSelector.cs
- BatchServiceHost.cs
- FontSource.cs
- UnknownBitmapEncoder.cs
- AssemblyHash.cs
- UnsafeNativeMethods.cs
- ListViewCancelEventArgs.cs
- SelfIssuedAuthAsymmetricKey.cs
- OracleRowUpdatingEventArgs.cs
- XamlToRtfWriter.cs
- webeventbuffer.cs
- ImageSourceConverter.cs
- SQLDecimal.cs
- BorderGapMaskConverter.cs
- CommonObjectSecurity.cs
- HttpListenerResponse.cs
- UxThemeWrapper.cs
- Expressions.cs
- CompiledRegexRunnerFactory.cs
- Ports.cs
- PositiveTimeSpanValidatorAttribute.cs
- CodeDelegateCreateExpression.cs
- InputProcessorProfilesLoader.cs
- AxHostDesigner.cs
- TextTabProperties.cs
- RemotingHelper.cs
- unsafenativemethodstextservices.cs
- ClientSettings.cs
- ClientUrlResolverWrapper.cs
- streamingZipPartStream.cs
- XmlCDATASection.cs
- Visitors.cs
- SwitchLevelAttribute.cs
- CaseInsensitiveHashCodeProvider.cs
- _ListenerAsyncResult.cs
- AbstractDataSvcMapFileLoader.cs
- SrgsToken.cs
- HostingEnvironmentException.cs
- COM2ExtendedBrowsingHandler.cs
- AggregateNode.cs
- CustomErrorsSectionWrapper.cs
- SimpleBitVector32.cs
- XPathMessageFilterElement.cs
- ContainerUIElement3D.cs
- DrawingContext.cs
- PathFigureCollection.cs
- CompositeDuplexElement.cs
- ListViewVirtualItemsSelectionRangeChangedEvent.cs
- VariableQuery.cs
- ThicknessKeyFrameCollection.cs
- StatusBarAutomationPeer.cs
- AutoGeneratedField.cs
- ContentPresenter.cs
- SecurityState.cs
- GeneralTransform3D.cs
- filewebresponse.cs
- _CookieModule.cs
- PropertySegmentSerializer.cs
- FormViewUpdateEventArgs.cs
- IsolatedStorageFile.cs
- ChannelEndpointElementCollection.cs
- Error.cs
- ViewBox.cs
- IDReferencePropertyAttribute.cs
- DBNull.cs
- ColumnProvider.cs
- MultilineStringConverter.cs
- GradientBrush.cs
- FixedElement.cs
- RichTextBoxConstants.cs
- DependencyObjectProvider.cs
- Menu.cs
- HtmlTitle.cs
- SingleAnimationBase.cs