0

使用 WCF 的发布者和订阅者概念,发布者(服务器)在 WCF 服务中开发,订阅者(客户端)在 Windows 应用程序中开发。发布者创建代理并实施我得到了错误

“提供给 ChannelFactory 的 InstanceContext 包含一个未实现 CallbackContractType 'IRegistrationCallback' 的 UserObject。

enter code here

服务器代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Reflection;
using System.IO;
using System.Configuration;
using System.ServiceModel.Description;

namespace ServerApp
{
    public partial class Form1 : Form, IService1, IDisposable
    {
        ServiceHost EventServiceHost = null;
        ServiceHost SubscriptionServiceHost = null;
        private bool disposed = false;
        string EndPoint1 = string.Empty;
        string EndPoint2 = string.Empty;
        string EndPoint3 = string.Empty;
        string EndPoint4 = string.Empty;
        string BaseAddress1 = string.Empty;
        string BaseAddress2 = string.Empty;
        FileStream fs = null;
        StreamWriter m_streamwriter = null;
        Subscription Subscribe = null;

    public Form1()
    {
        InitializeComponent();

        LogFile("Service Sucessfully lunched");
        EndPoint1 = ConfigurationSettings.AppSettings["EndpointAddress1"];
        EndPoint2 = ConfigurationSettings.AppSettings["EndpointAddress2"];
        EndPoint3 = ConfigurationSettings.AppSettings["EndpointAddress3"];
        EndPoint4 = ConfigurationSettings.AppSettings["EndpointAddress4"];
        BaseAddress1 = ConfigurationSettings.AppSettings["BaseAddress1"];
        BaseAddress2 = ConfigurationSettings.AppSettings["BaseAddress2"];
        InitializeOperation();
        Subscription.GetClientEvent += new GetClientListHandler(Subscription_GetClientEvent);
        Subscription.RemoveClientevent += new RemoveCleintListHandler(Subscription_RemoveClientevent);
        Subscribe = new Subscription();
    }

    void Subscription_RemoveClientevent(object obj)
    {
        try
        {
            string data = (string)obj;
            LogFile("Client Remove sucessfully: " + data);
        }
        catch (Exception ex)
        {
            LogFile("Client Remove failure: " + ex.Message);
        }
    }

    void Subscription_GetClientEvent(object obj)
    {
        try
        {
            string data = (string)obj;
            LogFile("Client Connect sucessfully: " + data);
        }
        catch (Exception ex)
        {
            LogFile("Client Connect failure: " + ex.Message);
        }
    }

    ~Form1()
    {
        CleanUp(false);
    }

    public void Dispose()
    {
        CleanUp(true);
        GC.SuppressFinalize(this);
    }
    private void CleanUp(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
            }
            try
            {
                if (EventServiceHost != null)
                    EventServiceHost.Close();
                if (SubscriptionServiceHost != null)
                    SubscriptionServiceHost.Close();
            }
            catch { }
        }
        disposed = true;
    }

    public void InitializeOperation()
    {
        try
        {
            Uri BaseAdrs1 = new Uri(BaseAddress1);
            Uri BaseAdrs2 = new Uri(BaseAddress2);
            EventServiceHost = new ServiceHost(typeof(Publishling), BaseAdrs1);
            System.ServiceModel.Channels.Binding wsDualBindingPublish = new WSDualHttpBinding(WSDualHttpSecurityMode.None);
            System.ServiceModel.Channels.Binding tcpBindingPublish = new NetTcpBinding(SecurityMode.None);

            EventServiceHost.AddServiceEndpoint(typeof(IEvent), wsDualBindingPublish, EndPoint1);
            EventServiceHost.AddServiceEndpoint(typeof(IEvent), tcpBindingPublish, EndPoint2);
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            EventServiceHost.Description.Behaviors.Add(smb);
            try
            {
                EventServiceHost.Open();
                LogFile("Publish Service Host open Sucessfully");
            }
            catch (Exception ex)
            {
                LogFile("Publish Service Host open failure: " + ex.Message);
            }
            SubscriptionServiceHost = new ServiceHost(typeof(Subscription), BaseAdrs2);
            System.ServiceModel.Channels.Binding wsDualBinding = new WSDualHttpBinding(WSDualHttpSecurityMode.None);
            System.ServiceModel.Channels.Binding tcpBinding = new NetTcpBinding(SecurityMode.None);

            SubscriptionServiceHost.AddServiceEndpoint(typeof(IRegistration), wsDualBinding, EndPoint3);
            SubscriptionServiceHost.AddServiceEndpoint(typeof(IRegistration), tcpBinding, EndPoint4);
            ServiceMetadataBehavior smb1 = new ServiceMetadataBehavior();
            smb1.HttpGetEnabled = true;
            SubscriptionServiceHost.Description.Behaviors.Add(smb1);
            try
            {
                SubscriptionServiceHost.Open();
                LogFile("Subscription Service Host open Sucessfully");
            }
            catch (Exception ex)
            {
                LogFile("Subscription Service Host open failure: " + ex.Message);
            }
        }
        catch (Exception ex)
        {
            LogFile("Service Host Configuration failure: " + ex.Message);
        }
    }

    public void Register(object obj)
    {
        Subscribe.Register(obj);
    }

    public void UnRegister(object obj)
    {
        Subscribe.UnRegister(obj);
    }

    public string GetDateTime()
    {
        return Subscribe.GetDateTime();
    }
    public void LogFile(string Data)
    {
        try
        {
            fs = new FileStream(@"c:\temp\WCFLogs.txt", FileMode.OpenOrCreate, FileAccess.Write);
            m_streamwriter = new StreamWriter(fs);
            m_streamwriter.BaseStream.Seek(0, SeekOrigin.End);
            m_streamwriter.WriteLine(DateTime.Now + " : " + Data + "\n");
        }
        catch
        {

        }
        finally
        {
            m_streamwriter.Flush();
            m_streamwriter.Close();
            m_streamwriter = null;
            fs.Close();
            fs = null;
        }
    }

    private void btnEvent_Click(object sender, EventArgs e)
    {
        try
        {
            if (listBox1.SelectedIndex >= 0)
            {
                Publishling ob1 = new Publishling();
                AlertData alertdata = PrepareAlertForReceiver();
                ob1.OnClient(listBox1.Items[listBox1.SelectedIndex], checkBox1.Checked);
                ob1.OnEvent(alertdata);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private AlertData PrepareAlertForReceiver()
    {
        AlertData e = new AlertData();
        e.SeqNo = "1";
        e.Description = "WCF Event";
        e.wer = "fg";
        return e;
    }
}

}
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        void Register(object obj);
    [OperationContract]
    void UnRegister(object obj);

    [OperationContract]
    string GetDateTime();

    // TODO: Add your service operations here
}

[ServiceContract]
interface IEvent
{
    [OperationContract(IsOneWay = true)]
    void OnEvent(AlertData e);

    [OperationContract(IsOneWay = true)]
    void OnClient(object obj, bool check);
}

[ServiceContract(CallbackContract = typeof(IEvent))]
public interface IRegistration
{
    [OperationContract]
    void Register(object obj);

    [OperationContract]
    void UnRegister(object obj);

    [OperationContract]
    string GetDateTime();
}

[DataContract]
public class AlertData
{
    private string _SeqNo;
    private string _Description;

    [DataMember]
    public string wer;

    [DataMember]
    public string SeqNo { get { return _SeqNo; } set { _SeqNo = value; } }

    [DataMember]
    public string Description { get { return _Description; } set { _Description = value; } }

}


public delegate void GetClientListHandler(object obj);
public delegate void RemoveCleintListHandler(object obj);

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Subscription : IRegistration
{
    public static event GetClientListHandler GetClientEvent;
    public static event RemoveCleintListHandler RemoveClientevent;

    static List<IEvent> m_ClientList;
    static List<object> ObjClientList;
    public GetClientListHandler ClientHandle = null;
    public RemoveCleintListHandler RemoveClinet = null;

    public Subscription()
    {
        m_ClientList = new List<IEvent>();
        ObjClientList = new List<object>();
        ClientHandle = new GetClientListHandler(GetClientLists);
        GetClientEvent += ClientHandle;
        RemoveClinet = new RemoveCleintListHandler(RemoveClientLists);
        RemoveClientevent += RemoveClinet;
    }

    internal static IEvent[] GetClientList()
    {
        lock (typeof(Subscription))
        {
            return m_ClientList.ToArray();
        }
    }

    internal static object[] GetClientListWithObj()
    {
        lock (typeof(Subscription))
        {
            return ObjClientList.ToArray();
        }
    }

    public void Register(object obj)
    {
        lock (typeof(Subscription))
        {
            IEvent Subscriber = OperationContext.Current.GetCallbackChannel<IEvent>();
            if (m_ClientList.Contains(Subscriber))
            {
                return;
            }
            m_ClientList.Add(Subscriber);
            ObjClientList.Add(obj);
            GetClientEvent(obj);
        }
    }

    public void UnRegister(object obj)
    {
        lock (typeof(Subscription))
        {
            IEvent Subscriber = OperationContext.Current.GetCallbackChannel<IEvent>();
            m_ClientList.Remove(Subscriber);
            ObjClientList.Remove(obj);
            RemoveClientevent(obj);
        }
    }

    public string GetDateTime()
    {
        return DateTime.Now.ToString();
    }

    public void GetClientLists(object obj)
    {

    }

    public void RemoveClientLists(object obj)
    {

    }
}

public class Publishling : IEvent
{
    object ClientObj = null;
    bool CheckAll = false;

    public void OnEvent(AlertData e)
    {
        if (CheckAll)
        {
            IEvent[] Subscribers = Subscription.GetClientList();
            Type type = typeof(IEvent);
            MethodInfo methodinfo = type.GetMethod("OnEvent");

            foreach (IEvent Subscriber in Subscribers)
            {
                try
                {
                    methodinfo.Invoke(Subscriber, new object[] { e });
                }
                catch
                {
                }
            }
        }
        else
        {
            int i = 0;
            IEvent[] Subscribersevent = Subscription.GetClientList();
            object[] Subscribers = Subscription.GetClientListWithObj();
            Type type = typeof(IEvent);
            MethodInfo methodinfo = type.GetMethod("OnEvent");
            foreach (object Subscriber in Subscribers)
            {
                try
                {
                    if (ClientObj == Subscriber)
                    {
                        methodinfo.Invoke(Subscribersevent[i], new object[] { e });
                        break;
                    }
                    i++;
                }
                catch
                { i++; }
            }
        }
    }

    public void OnClient(object obj, bool check)
    {
        ClientObj = obj;
        CheckAll = check;
    }
}

应用程序配置

<configuration>
  <appSettings>
    <add key="BaseAddress1"  value="http://192.168.0.194:8001/PublishingService/" />
    <add key="BaseAddress2"  value="http://192.168.0.194:8002/SubscriptionServie/" />
    <add key="EndpointAddress2"  value="net.tcp://192.168.0.194:8004/PublishingService" />
    <add key="EndpointAddress1"  value="http://192.168.0.194:8003/PublishingService/" />
    <add key="EndpointAddress4"  value="net.tcp://192.168.0.194:8006/SubscriptionServie" />
    <add key="EndpointAddress3"  value="http://192.168.0.194:8005/SubscriptionServie/" />
  </appSettings>
</configuration>

代理代码

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.3053
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Runtime.Serialization;



[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="AlertData", Namespace="http://schemas.datacontract.org/2004/07/")]
public partial class AlertData : object, System.Runtime.Serialization.IExtensibleDataObject

{


private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

private string DescriptionField;

private string SeqNoField;

private string werField;

public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
    get
    {
        return this.extensionDataField;
    }
    set
    {
        this.extensionDataField = value;
    }
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string Description
{
    get
    {
        return this.DescriptionField;
    }
    set
    {
        this.DescriptionField = value;
    }
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string SeqNo
{
    get
    {
        return this.SeqNoField;
    }
    set
    {
        this.SeqNoField = value;
    }
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string wer
{
    get
    {
        return this.werField;
    }
    set
    {
        this.werField = value;
    }
}
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IRegistration", CallbackContract=typeof(IRegistrationCallback))]
public interface IRegistration
{


[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IRegistration/Register", ReplyAction="http://tempuri.org/IRegistration/RegisterResponse")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(AlertData))]
void Register(object obj);

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IRegistration/UnRegister", ReplyAction="http://tempuri.org/IRegistration/UnRegisterResponse")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(AlertData))]
void UnRegister(object obj);

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IRegistration/GetDateTime", ReplyAction="http://tempuri.org/IRegistration/GetDateTimeResponse")]
string GetDateTime();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IRegistrationCallback
{


[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IRegistration/OnEvent")]
void OnEvent(AlertData e);

[System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IRegistration/OnClient")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(AlertData))]
void OnClient(object obj, bool check);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IRegistrationChannel : IRegistration, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class RegistrationClient : System.ServiceModel.DuplexClientBase<IRegistration>, IRegistration

{


public RegistrationClient(System.ServiceModel.InstanceContext callbackInstance) : 
        base(callbackInstance)
{
}

public RegistrationClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) : 
        base(callbackInstance, endpointConfigurationName)
{
}

public RegistrationClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) : 
        base(callbackInstance, endpointConfigurationName, remoteAddress)
{
}

public RegistrationClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
        base(callbackInstance, endpointConfigurationName, remoteAddress)
{
}

public RegistrationClient(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
        base(callbackInstance, binding, remoteAddress)
{
}

public void Register(object obj)
{
    base.Channel.Register(obj);
}

public void UnRegister(object obj)
{
    base.Channel.UnRegister(obj);
}

public string GetDateTime()
{
    return base.Channel.GetDateTime();
}
}

代理配置文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IRegistration" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                    maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
                    maxReceivedMessageSize="65536">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="None">
                        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IRegistration" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                    <security mode="None">
                        <message clientCredentialType="Windows" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsDualHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://192.168.0.194:8005/SubscriptionServie/"
                binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IRegistration"
                contract="IRegistration" name="WSDualHttpBinding_IRegistration" />
            <endpoint address="net.tcp://192.168.0.194:8006/SubscriptionServie"
                binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IRegistration"
                contract="IRegistration" name="NetTcpBinding_IRegistration" />
        </client>
    </system.serviceModel>
</configuration>

客户代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.Net;
using System.Configuration;

namespace ClientApp
{
    public partial class Form1 : Form
    {
        static int eventReceiveCount;
        static int astaEventReceiveCount;
        WCFIntermediate CommunicationObject = null;
        string EndPoint = string.Empty;
        string EndPoint1 = string.Empty;
        static object ClientObj = null;

    public Form1()
    {
        InitializeComponent();
        InitializeClient();
    }

    private void InitializeClient()
    {
        EndPoint = ConfigurationSettings.AppSettings["EndpointAddress"];
        EndPoint1 = ConfigurationSettings.AppSettings["EndpointAddress1"];

        CommunicationObject = new WCFIntermediate();
        if (rbtnHttp.Checked)
        {
            CommunicationObject.MakeClient(EndPoint1, this, 1);
        }
        else if (rbtnTcp.Checked)
        {
            CommunicationObject.MakeClient(EndPoint, this, 0);
        }
        eventReceiveCount = 0;
        astaEventReceiveCount = 0;
    }

    public void OnEvent(AlertData e)
    {
        if (e != null)
        {
            int itemNum = (lvAsta.Items.Count < 1) ? 0 : lvAsta.Items.Count;
            lvAsta.Items.Add(itemNum.ToString());
            lvAsta.Items[itemNum].SubItems.AddRange(new string[] { e.SeqNo.ToString(), e.Description });
            astaEventReceiveCount += 1;
            txtAstaEventCount.Text = astaEventReceiveCount.ToString();
        }
    }

    private void btnClearAstaListView_Click(object sender, EventArgs e)
    {
        lvAsta.Items.Clear();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        textBox1.Text = CommunicationObject.GetDateTime();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            Random rnd = new Random();
            string strHostName = Dns.GetHostName();
            IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
            IPAddress[] addr = ipEntry.AddressList;
            ClientObj = addr[0].ToString() + ":" + rnd.Next(5);
            if (CommunicationObject == null)
                InitializeClient();
            CommunicationObject.Subscribe(ClientObj);
            ((Button)sender).Enabled = false;
            button2.Enabled = true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        ((Button)sender).Enabled = false;
        button1.Enabled = true;
        CommunicationObject.UnSubscribe(ClientObj);
        CommunicationObject = null;
    }

    private void rbtnTcp_CheckedChanged(object sender, EventArgs e)
    {
        if (rbtnTcp.Checked)
        {
            if (CommunicationObject == null)
            {
                CommunicationObject = new WCFIntermediate();
                CommunicationObject.MakeClient(EndPoint, this, 0);
            }
        }
    }

    private void rbtnHttp_CheckedChanged(object sender, EventArgs e)
    {
        if (rbtnHttp.Checked)
        {
            if (CommunicationObject == null)
            {
                CommunicationObject = new WCFIntermediate();
                CommunicationObject.MakeClient(EndPoint1, this, 1);
            }
        }
    }
}



class WCFIntermediate
{
    IRegistration m_Proxy;

    public void MakeClient(string EndpoindAddress, object CallbackInstance, int TcpOrHttp)
    {
        if (TcpOrHttp == 0)
        {
            NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None);
            EndpointAddress endPointaddress = new EndpointAddress(EndpoindAddress);
            InstanceContext Context = new InstanceContext(CallbackInstance);
            m_Proxy = new RegistrationClient(Context, netTcpBinding, endPointaddress);
        }
        else if (TcpOrHttp == 1)
        {

            WSDualHttpBinding DualHttpBinding = new WSDualHttpBinding(WSDualHttpSecurityMode.None);
            EndpointAddress endPointaddress1 = new EndpointAddress(EndpoindAddress);
            InstanceContext Context1 = new InstanceContext(CallbackInstance);
            m_Proxy = new RegistrationClient(Context1, DualHttpBinding, endPointaddress1);

            string strHostName = Dns.GetHostName();
            //IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
            IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
            IPAddress[] addr = ipEntry.AddressList;
            DualHttpBinding.ClientBaseAddress = new Uri("http://" + addr[0].ToString() + ":4000/");
        }
    }

    public void Subscribe(object obj)
    {
        m_Proxy.Register(obj);
    }

    public void UnSubscribe(object eventOpertion)
    {
        m_Proxy.UnRegister(eventOpertion);
    }

    public string GetDateTime()
    {
        return m_Proxy.GetDateTime();
    }
}
}
4

1 回答 1

1

您的客户端部分没有实现 IRegistrationCallback。

于 2010-12-31T12:45:31.033 回答