发布者和订阅者概念使用WCF,发布者(Server)在WCF服务和订阅者(Client)中开发以在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();
}
}
}
答案 0 :(得分:1)
您的客户端部分未实现IRegistrationCallback。