示例#1
0
 private void SetMessageId(Message message)
 {
     if (message.MustBeReliable || message.PreferReliable)
     {
         message.Header.MessageId = MessageSerializer.GetNextMessageId(ref this.nextReliableMessageId);
     }
     else
     {
         message.Header.MessageId = MessageSerializer.GetNextMessageId(ref this.nextMessageId);
     }
 }
示例#2
0
        private Task <bool> SendMessage(Message message, bool isResponse, bool requestingResponse, int responseTimeout, out Task <Message> responseTask)
        {
            string callCategory = null;

                        #if TRACE
            int c = GetNextCallId();
            callCategory = String.Format("{1}:{2} {3}:Send({0})", message, this.typeName, this.connectionId, c);
                        #endif
            Trace.WriteLineIf(NTrace.TraceVerbose, "Entering", callCategory);

            responseTask = null;

            TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool> (message);

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (!IsConnected)
            {
                Trace.WriteLineIf(NTrace.TraceVerbose, "Exiting (not connected)", callCategory);
                tcs.SetResult(false);

                if (requestingResponse)
                {
                    var responseTcs = new TaskCompletionSource <Message>();
                    responseTcs.SetCanceled();
                    responseTask = responseTcs.Task;
                }

                return(tcs.Task);
            }

            SocketAsyncEventArgs eargs = null;
                        #if NET_4
            if (!writerAsyncArgs.TryPop(out eargs))
            {
                while (eargs == null)
                {
                    int count = bufferCount;
                    if (count == sendBufferLimit)
                    {
                        Trace.WriteLineIf(NTrace.TraceVerbose, "Waiting for writer args", callCategory);

                        SpinWait wait = new SpinWait();
                        while (!writerAsyncArgs.TryPop(out eargs))
                        {
                            wait.SpinOnce();
                        }
                    }
                    else if (count == Interlocked.CompareExchange(ref bufferCount, count + 1, count))
                    {
                        Trace.WriteLineIf(NTrace.TraceVerbose, "Creating new writer args", callCategory);

                        eargs = new SocketAsyncEventArgs();
                        eargs.SetBuffer(new byte[1024], 0, 1024);
                        eargs.Completed += ReliableSendCompleted;
                    }
                }
            }
                        #else
            while (eargs == null)
            {
                lock (writerAsyncArgs)
                {
                    if (writerAsyncArgs.Count != 0)
                    {
                        eargs = writerAsyncArgs.Pop();
                    }
                    else if (bufferCount != sendBufferLimit)
                    {
                        bufferCount++;
                        eargs = new SocketAsyncEventArgs();
                        eargs.SetBuffer(new byte[1024], 0, 1024);
                        eargs.Completed += ReliableSendCompleted;
                    }
                }
            }
                        #endif

                        #if !SILVERLIGHT
            eargs.AcceptSocket = null;
                        #endif

            Trace.WriteLineIf(NTrace.TraceVerbose, "Have writer args", callCategory);

            bool sent;
            lock (this.sendSync) {
                if (message.Header == null)
                {
                    message.Header = new MessageHeader();
                }

                message.Header.MessageId = MessageSerializer.GetNextMessageId(ref this.nextMessageId);

                if (requestingResponse)
                {
                    responseTask = Responses.SendFor(message, tcs.Task, responseTimeout);
                }

                MessageSerializer slzr = this.serializer;
                if (slzr == null)
                {
                    int sp = Interlocked.Decrement(ref this.pendingAsync);
                    Trace.WriteLineIf(NTrace.TraceVerbose, String.Format("Decrement pending: {0}", sp), callCategory);

                                        #if !NET_4
                    lock (writerAsyncArgs)
                                        #endif
                    writerAsyncArgs.Push(eargs);

                    Trace.WriteLineIf(NTrace.TraceVerbose, "Exiting (serializer is null, probably disconnecting)", callCategory);
                    tcs.SetResult(false);
                    return(tcs.Task);
                }

                int    length;
                byte[] buffer = slzr.GetBytes(message, out length, eargs.Buffer);

                eargs.SetBuffer(buffer, 0, length);
                eargs.UserToken = new KeyValuePair <NetworkConnection, TaskCompletionSource <bool> > (this, tcs);

                int p = Interlocked.Increment(ref this.pendingAsync);
                Trace.WriteLineIf(NTrace.TraceVerbose, String.Format("Increment pending: {0}", p), callCategory);

                if (!IsConnected)
                {
                    Interlocked.Decrement(ref this.pendingAsync);
                    Trace.WriteLineIf(NTrace.TraceVerbose, String.Format("Decrement pending: {0}", p), callCategory);

                                        #if !NET_4
                    lock (writerAsyncArgs)
                                        #endif
                    writerAsyncArgs.Push(eargs);

                    tcs.SetResult(false);
                    return(tcs.Task);
                }

                Trace.WriteLineIf(NTrace.TraceVerbose, "Sending", callCategory);
                sent = !this.reliableSocket.SendAsync(eargs);
            }

            if (sent)
            {
                Trace.WriteLineIf(NTrace.TraceVerbose, "Send completed synchronously", callCategory);
                ReliableSendCompleted(this.reliableSocket, eargs);
            }

            Trace.WriteLineIf(NTrace.TraceVerbose, "Exiting", callCategory);
            return(tcs.Task);
        }