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
- Helpers.cs
- DurableMessageDispatchInspector.cs
- RepeaterItemEventArgs.cs
- FrameworkObject.cs
- ModelItemDictionary.cs
- FormViewDeletedEventArgs.cs
- AssemblyBuilder.cs
- TraceLog.cs
- BufferedConnection.cs
- DataListCommandEventArgs.cs
- BaseTemplateBuildProvider.cs
- ReferenceSchema.cs
- TemplatedMailWebEventProvider.cs
- IPEndPointCollection.cs
- ListView.cs
- DescendentsWalker.cs
- FileLoadException.cs
- XmlCustomFormatter.cs
- TrackingSection.cs
- Nodes.cs
- PaperSize.cs
- Html32TextWriter.cs
- WebPartHeaderCloseVerb.cs
- Metadata.cs
- RelationshipDetailsCollection.cs
- TextBox.cs
- TextFormatter.cs
- InputChannelAcceptor.cs
- HandlerWithFactory.cs
- ListView.cs
- FixedTextView.cs
- TypeFieldSchema.cs
- SafeHandle.cs
- COM2PropertyDescriptor.cs
- TriState.cs
- XmlValueConverter.cs
- BitmapEncoder.cs
- VersionedStream.cs
- ThreadInterruptedException.cs
- NativeMethods.cs
- TreeNodeMouseHoverEvent.cs
- EnumConverter.cs
- XmlUtf8RawTextWriter.cs
- DataGridDetailsPresenter.cs
- EnumBuilder.cs
- DataGridColumnEventArgs.cs
- HitTestParameters3D.cs
- MouseEvent.cs
- ComplexPropertyEntry.cs
- AsynchronousChannelMergeEnumerator.cs
- DataGridBoundColumn.cs
- XamlDesignerSerializationManager.cs
- SafeNativeMethods.cs
- WizardStepBase.cs
- CachedCompositeFamily.cs
- MailFileEditor.cs
- GridViewRowCollection.cs
- MemoryRecordBuffer.cs
- JavascriptCallbackMessageInspector.cs
- ProgressBar.cs
- XamlWrapperReaders.cs
- SignatureHelper.cs
- DataListItemEventArgs.cs
- MobileDeviceCapabilitiesSectionHandler.cs
- PrintDocument.cs
- SecuritySessionSecurityTokenProvider.cs
- AutoGeneratedFieldProperties.cs
- BindUriHelper.cs
- ActivityExecutionFilter.cs
- MarkerProperties.cs
- ElementProxy.cs
- PerformanceCounterLib.cs
- XmlDocumentType.cs
- LineServicesCallbacks.cs
- CommandSet.cs
- SubMenuStyleCollection.cs
- ChannelBuilder.cs
- OdbcPermission.cs
- SignatureResourcePool.cs
- EntitySqlException.cs
- HttpResponse.cs
- DrawingServices.cs
- MessageLogTraceRecord.cs
- Parsers.cs
- BlurBitmapEffect.cs
- ResXResourceReader.cs
- Expression.cs
- MultiSelectRootGridEntry.cs
- TimeIntervalCollection.cs
- CookielessData.cs
- BinaryFormatter.cs
- LicenseException.cs
- SimpleColumnProvider.cs
- SymLanguageType.cs
- GeometryModel3D.cs
- DispatcherHookEventArgs.cs
- WebGetAttribute.cs
- UrlAuthorizationModule.cs
- UnsafeNativeMethods.cs
- SynchronizedPool.cs