Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6012585
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T02:25:31+00:00 2026-05-23T02:25:31+00:00

I have a small WCF pub/sup service running, and remote clients subscribe and send

  • 0

I have a small WCF pub/sup service running, and remote clients subscribe and send messages (tried will all sorts of complex objects) and that works fine. All interfaces reflect(ed) the type of object being used. Switching to another object type requires that the interfaces be adjusted to accommodate that object type. All subscribers get a copy of the message.

Now I am trying to do the same thing, but with Message class messages. Client creates a new message and encapsulates its object in the message, and sends it to the (remote) service, where it is received properly (inspected the object). However, when the server replies by resending (callback) the message back to the originating client, the client receives the following message:

“The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.”

Sequence of events (Client):

Client creates Message,
(DuplexChannelFactory)AddMessage,
-Catch above error

Sequence of events (Server):

Service host receives message,
Message inspected (copy and recreate),
Perform callback,
No errors.

Switching back to a basic, or user defined, type and all problems go away. I have been struggling with this for a week now and not closer to any solution. Tried manipulating headers, recreating the message, switching to Message Contracts, and trying to interpret the contents of the trace logs etc. Hope I will find some answers here.

Primary code used (stripped of most of the error handling):

Client interfaces:

namespace WCFSQL
{
    public class ClientInterfaces
    {

        [ServiceContract(Namespace = "WCFServer", Name = "CallBacks")]
        public interface IMessageCallback
        {
            [OperationContract(Name = "OnMessageAdded", Action = "WCFServer/IMessageCallback/OnMessageAdded", IsOneWay = true)] 
            void OnMessageAdded(Message SQLMessage, DateTime timestamp);
        }

        [ServiceContract(Namespace = "WCFServer", CallbackContract = typeof(IMessageCallback))] 
        public interface IMessage
        {
            [OperationContract(Name = "AddMessage", Action = "WCFServer/IMessage/AddMessage")]
            void AddMessage(Message SQLMessage);

            [OperationContract(Name = "Subscribe", Action = "WCFServer/IMessage/Subscribe")]
            bool Subscribe();

            [OperationContract(Name = "Unsubscribe", Action = "WCFServer/IMessage/Unsubscribe")]
            bool Unsubscribe();
        }
    }
}

Server interfaces:

namespace WCFSQL
{
    public class ServerInterfaces
    {
        [ServiceContract(Namespace = "WCFServer")]
        public interface IMessageCallback
        {
            [OperationContract(Name = "OnMessageAdded", Action = "WCFServer/IMessageCallback/OnMessageAdded", IsOneWay = true)]
            void OnMessageAdded(Message SQLMessage, DateTime timestamp); 
        }

        [ServiceContract(Namespace = "WCFServer", CallbackContract = typeof(IMessageCallback), SessionMode = SessionMode.Required)]
        public interface IMessage
        {
            [OperationContract(Name = "AddMessage", Action = "WCFServer/IMessage/AddMessage")]
            void AddMessage(Message SQLMessage);

            [OperationContract(Name = "Subscribe", Action = "WCFServer/IMessage/Subscribe")]
            bool Subscribe();

            [OperationContract(Name = "Unsubscribe", Action = "WCFServer/IMessage/Unsubscribe")]
            bool Unsubscribe();
        }
    }
}

Message creation:

// client proxy instance created and opened before

    public static bool WCFSqlLogger(string Program, WCFSQLErrorLogMessage SQLErrorMessage, WCFSqlClientProxy client)
    {
        MessageVersion ver = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10);

        Message Out = Message.CreateMessage(ver, "WCFServer/IMessage/AddMessage", SQLErrorMessage); 

        if (!client.SendMessage(Out))
        {
            Console.WriteLine("Client Main: Unable to send");
            return false;
        }
        return true;
    }

Client proxy:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
[CallbackBehavior(IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext = false)] 
public class WCFSqlClientProxy : ClientInterfaces.IMessageCallback, IDisposable
{
    public ClientInterfaces.IMessage pipeProxy = null;
    DuplexChannelFactory<ClientInterfaces.IMessage> pipeFactory;

    public bool Connect()
    {
        NetTcpBinding newBinding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);// NetTcpBinding newBinding = new NetTcpBinding(SecurityMode.Transport)
        newBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
        EndpointAddress newEndpoint = new EndpointAddress(new Uri("net.tcp://host:8000/ISubscribe"), EndpointIdentity.CreateDnsIdentity("Domain")); 

        pipeFactory = new DuplexChannelFactory<ClientInterfaces.IMessage>(new InstanceContext(this), newBinding, newEndpoint); 

        pipeFactory.Credentials.Peer.PeerAuthentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
        pipeFactory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck; 
        pipeFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "somestring");

        try
        {
            pipeProxy = pipeFactory.CreateChannel();
            pipeProxy.Subscribe();
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine("Error opening: {0}", e.Message);
            return false;
        }
    }
    public void Close()
    {
        pipeProxy.Unsubscribe();
    }

    public bool SendMessage(Message SQLMessage)
    {
        try
        {
            Console.WriteLine("Proxy Sending:");
            pipeProxy.AddMessage(SQLMessage); // This is where the eror occurs !!!!!!!!!!!!!!!!!!
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine("Client Proxy: Error sending: {0}", e.Message); 
        }
        return false;
    }

    public void OnMessageAdded(Message SQLMessage, DateTime timestamp) 
    {
        WCFSQLErrorLogMessage message = SQLMessage.GetBody<WCFSQLErrorLogMessage>();
        Console.WriteLine(message.LogProgram + ": " + timestamp.ToString("hh:mm:ss"));
    }

    public void Dispose()
    {
        Console.WriteLine("Dispose: Unsubscribe");
        pipeProxy.Unsubscribe();
    }
}

Service:

namespace WCFSQL
{

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
[CallbackBehavior(IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext = false)] // or ConcurrencyMode.Reentrant
public class WCFSqlServerProxy : ServerInterfaces.IMessage
{
    private static List<ServerInterfaces.IMessageCallback> subscribers = new List<ServerInterfaces.IMessageCallback>(); 
    private static Uri target;
    private static ServiceHost serviceHost;

    public WCFSqlServerProxy(Uri Target) // Singleton
    {
        target = Target;
    }

    public bool Connect()
    {
        serviceHost = new ServiceHost(typeof(WCFSqlServerProxy), target);
        NetTcpBinding newBinding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
        newBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate; 
        newBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; 
        serviceHost.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck; // Non-domain members cannot follow the chain?
        serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "somestring");
        serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
        serviceHost.AddServiceEndpoint(typeof(ServerInterfaces.IMessage), newBinding, "ISubscribe");

        return true;
    }

    public bool Open()
    {
        serviceHost.Open();
    return true;
    }

    public bool Close()
    {
        serviceHost.Close();
        return true;
    }

    public bool Subscribe()
    {
        try
        {
            ServerInterfaces.IMessageCallback callback = OperationContext.Current.GetCallbackChannel<ServerInterfaces.IMessageCallback>();
            if (!subscribers.Contains(callback))
            {
                subscribers.Add(callback);
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (Exception e)
        {
            return false;
        }
    }

    public bool Unsubscribe()
    {
        try
        {
            ServerInterfaces.IMessageCallback callback = OperationContext.Current.GetCallbackChannel<ServerInterfaces.IMessageCallback>(); 
            if (subscribers.Contains(callback))
            {
                subscribers.Remove(callback);
                return true;
            }
            return false;
        }
        catch (Exception e)
        {
            Console.WriteLine("WCFSqlServerProxy: Unsubscribe - Unsubscribe error {0}", e);
            return false;
        }
    }

    private string GetData()
    {
        MessageProperties messageProperties = ((OperationContext)OperationContext.Current).IncomingMessageProperties;
        RemoteEndpointMessageProperty endpointProperty = messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
        string computerName = null;
        try
        {
            string[] computer_name = Dns.GetHostEntry(endpointProperty.Address).HostName.Split(new Char[] { '.' });
            computerName = computer_name[0].ToString();
        }
        catch (Exception e)
        {
            computerName = "NOTFOUND";
            Console.WriteLine("WCFSqlServerProxy: Hostname error:  {0}", e);
        }
        return string.Format("{0} - {1}:{2}", computerName, endpointProperty.Address, endpointProperty.Port);
    }


    public void AddMessage(Message SQLMessage) //Go through the list of connections and call their callback funciton
    {
        subscribers.ForEach(delegate(ServerInterfaces.IMessageCallback callback)
        {
            if (((ICommunicationObject)callback).State == CommunicationState.Opened)
            {
                MessageVersion ver = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10);
                MessageBuffer buffer = SQLMessage.CreateBufferedCopy(4096);

                Message msgCopy = buffer.CreateMessage();
                //System.Xml.XmlDictionaryReader xrdr = msgCopy.GetReaderAtBodyContents();

                WCFSQLErrorLogMessage p = msgCopy.GetBody<WCFSQLErrorLogMessage>();

                SQLMessage = buffer.CreateMessage();
                buffer.Close();

                Message In = Message.CreateMessage(ver, "WCFServer/IMessage/AddMessage", p); // Tried recreating messsage, with same results

                //Console.WriteLine("Message: Header To:      {0}", In.Headers.To);
                //Console.WriteLine("Message: Header From:    {0}", In.Headers.From);
                //Console.WriteLine("Message: Header Action:  {0}", In.Headers.Action);
                //Console.WriteLine("Message: Header ReplyTo: {0}", In.Headers.ReplyTo);
                //Console.WriteLine("Message: IsFault:        {0}", In.IsFault);
                //Console.WriteLine("Message: Properties      {0}", In.Properties);
                //Console.WriteLine("Message: State           {0}", In.State);
                //Console.WriteLine("Message: Type            {0}", In.GetType());
                //Console.WriteLine("Proxy Sending: Copy created");

                //Console.WriteLine("Remote:  {0}, Hash: {1}", GetData(), callback.GetHashCode());

                callback.OnMessageAdded(SQLMessage, DateTime.Now); // This should echo the message back with a timeslot.
            }
            else
            {
                Console.WriteLine("WCFSqlServerProxy:addmessage connected state: {0}", ((ICommunicationObject)callback).State == CommunicationState.Opened);
                subscribers.Remove(callback);
            }
        });
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T02:25:32+00:00Added an answer on May 23, 2026 at 2:25 am

    I just got an answer to my question from Tanvir Huda, on the microsoft WCF forum.

    “Using the Message Class in Operations

    You can use the Message class as an input parameter of an operation, the return value of an operation, or both. If Message is used anywhere in an operation, the following restrictions apply:

    •The operation cannot have anyoutorrefparameters.

    •There cannot be more than oneinputparameter. If the parameter is present, it must be either Message or a message contract type.

    •The return type must be either void,Message, or a message contract type.”

    I cannot beleive I missed that; must have read it at least three times, but never applied those rules to the callback. The callback in my interfaces described, do have a return type of void, but it has a Message and a DateTime parameter.

    After removing the DateTime parameter, the callback did (try) to re-serialize the original Message, but failed because of on invalid action (action was still set for the AddMessage, while now it should be OnMessageAdded). After changing the action on the callback to Action=”*” it workt perfectly. A (maybe annoying) detail it that i do not really require a Message type on the callback, but I was very frustrated that I did not get it to work

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an already running basicHttpBinding with transferMode=Buffered WCF service for sending small amount
I have a small WCF hosting engine that I am writing that will dynamically
Here is question for all those who have delivered WCF solutions to their clients/customers
I have developed a small WCF service which handles HTTP request. I want to
I have develope a small web application in that i am using wcf service,I
I have a small WCF service which is executed on an XP box with
I have to create a WCF service that will accept thousands of requests every
Heres my situation: I have a RESTful WCF service running on my server, the
We have a small console application (under 200kb) that will be distributed to clients
i have small function that running on condintion, if text box value is not

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.