Search code examples
wcfcachingduplex-channel

How can I change message in DuplexSessionChannel (tcpTransport) in WCF custom channel?


I implement IDuplexSessionChannel on my Custom Channel because I use tcpTransport. In that custom channel, I cache service call response(client side caching). But it has errors. In IRequestChannel it works fine. How can I change message in TryMessage method. My code :

public Message Receive(TimeSpan timeout)
    {
        Message response = null;
        response = CommunicationCacheManager.Get(_request.Headers.Action, _request);

        if (response == null)
        {
            response = this.InnerChannel.Receive(timeout);
            int cacheTimeout = 0;
            if (response.Headers.FindHeader(Constants.CacheTimeOutHeader.NAME, Constants.CacheTimeOutHeader.NAMESPACE) > -1)
            {
                cacheTimeout = response.Headers.GetHeader<int>(Constants.CacheTimeOutHeader.NAME, Constants.CacheTimeOutHeader.NAMESPACE);
            }
            if (cacheTimeout > 0 && response != null &&
                    !response.IsFault &&
                    !response.IsEmpty)
            {
                CommunicationCacheManager.Add(_request.Headers.Action, cacheTimeout, ref response);
            }
        }
        return response;
    }

    public Message Receive()
    {
        return this.InnerChannel.Receive();
    }

    public bool TryReceive(TimeSpan timeout, out Message message)
    {
        ThrowIfDisposedOrNotOpen();
        message = null;
        bool timedout = false;
        try
        {
            message = this.Receive(timeout);
        }
        catch (TimeoutException)
        {
            timedout = true;
        }
        return (!timedout);
    }

CacheManager works. And I get the response Cache. But tryReceive run again and when I look Message. Message is closed. How can I fix that


Solution

  • Problem is solved.

    Tcp Binding add RelatesTo Header to Message. So code is changed to

    public Message Receive(TimeSpan timeout)
    {
        Message response = null;
        response = CommunicationCacheManager.Get(_request.Headers.Action, _request);
    
        if (response == null)
        {
            response = this.InnerChannel.Receive(timeout);
            int cacheTimeout = 0;
            if (response.Headers.FindHeader(Constants.CacheTimeOutHeader.NAME, Constants.CacheTimeOutHeader.NAMESPACE) > -1)
            {
                cacheTimeout = response.Headers.GetHeader<int>(Constants.CacheTimeOutHeader.NAME, Constants.CacheTimeOutHeader.NAMESPACE);
            }
            if (cacheTimeout > 0 && response != null &&
                    !response.IsFault &&
                    !response.IsEmpty)
            {
                CommunicationCacheManager.Add(_request.Headers.Action, cacheTimeout, ref response);
            }
        }
        else
        {
           response.Headers.RelatesTo=_request.Header.MessageId;
        }
        return response;
    }