我有Winforms
个托管WCF
服务的应用程序。
这是我的Button connect event
:
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
// Returns a list of ipaddress configuration
IPHostEntry ips = Dns.GetHostEntry(Dns.GetHostName());
// Get machine ipaddress
IPAddress _ipAddress = IPAddress.Parse(tbServerIp.Text);
// Create the url that is needed to specify where the service should be started
urlService = "net.tcp://" + _ipAddress.ToString() + ":8000/MyService";
// Instruct the ServiceHost that the type that is used is a ServiceLibrary.service1
host = new ServiceHost(typeof(ServiceLibrary.service1));
host.Opening += new EventHandler(host_Opening);
host.Opened += new EventHandler(host_Opened);
host.Closing += new EventHandler(host_Closing);
host.Closed += new EventHandler(host_Closed);
// The binding is where we can choose what transport layer we want to use. HTTP, TCP ect.
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.TransactionFlow = false;
tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
tcpBinding.Security.Mode = SecurityMode.None; // <- Very crucial
// Add a endpoint
host.AddServiceEndpoint(typeof(ServiceLibrary.IService1), tcpBinding, urlService);
// A channel to describe the service. Used with the proxy scvutil.exe tool
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metadataBehavior == null)
{
// This is how I create the proxy object that is generated via the svcutil.exe tool
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetUrl = new Uri("http://" + _ipAddress.ToString() + ":8001/MyService");
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.ToString();
host.Description.Behaviors.Add(metadataBehavior);
urlMeta = metadataBehavior.HttpGetUrl.ToString();
//pbIndicator.Image = Resources.indicator_green;
btnConnect.BackColor = Color.Red;
btnConnect.Text = "Stop";
}
host.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace);
}
}
这是我的ServiceLibrary:
namespace ServiceLibrary
{
public delegate void StatusEventHandler(string srt);
[ServiceContract()]
public interface IService1
{
[OperationContract]
string MyOperation1(string myValue);
[OperationContract]
string MyOperation2(DataContract1 dataContractValue);
[OperationContract]
string HelloWorld(string str);
}
public class service1 : IService1
{
public event StatusEventHandler StartEvent;
public string MyOperation1(string myValue)
{
return "Hello: " + myValue;
}
public string MyOperation2(DataContract1 dataContractValue)
{
return "Hello: " + dataContractValue.FirstName;
}
public string HelloWorld(string str)
{
StartEvent(str);
//return "Helloworld from " + str;
}
}
[DataContract]
public class DataContract1
{
string firstName;
string lastName;
[DataMember]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
[DataMember]
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
}
我想要做的是将客户端消息从HelloWorld function
传递到我的主表单,所以我尝试在class service1
内创建事件:
public delegate void StatusEventHandler(string srt);
public event StatusEventHandler StartEvent;
但即使从我的主表单(在我的按钮点击事件内)注册后它仍然为null 实现这一目标的最简单方法是什么?
答案 0 :(得分:0)
当您创建服务主机时,您提供了一个类型,这意味着每次调用您的服务时,都会创建该类型的新实例。
host = new ServiceHost(typeof(ServiceLibrary.service1));
您需要将服务实例传递给servicehost构造函数,因此每次调用都将使用该实例。
var yourServiceInstance = new ServiceLibrary.service1();
// attach event handlers here
host = new ServiceHost(yourServiceInstance);
执行此操作时,需要为单实例模式配置服务类:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class service1
{
// methods here
}