在工作中經常使用WinForm來承載多個WCF服務,由於底層代碼無權查看,故自己研究寫了一個類實現同樣的功能並加入對單個WCS服務的控制,能夠選擇其中的一個會多個服務進行啟動,停止的控制,並且支持雙工通訊模式,廢話不多說直接上代碼: namespace Gaofajin.Net{ public cl ...
在工作中經常使用WinForm來承載多個WCF服務,由於底層代碼無權查看,故自己研究寫了一個類實現同樣的功能並加入對單個WCS服務的控制,能夠選擇其中的一個會多個服務進行啟動,停止的控制,並且支持雙工通訊模式,廢話不多說直接上代碼:
namespace Gaofajin.Net
{
public class WcfRunerNew
{
#region 變數定義
public int Port { get; set; } = 8080;
public bool IsRunning = false;
List<WcfStruct> list = new List<WcfStruct>() ;
// public bool UseDuplex { get; } = false;
#endregion
#region 構造函數
public WcfRunerNew(int port)
{
Port = port;
}
public WcfRunerNew()
{
}
System.ServiceModel.Channels.Binding InitBinding(bool duplex)
{
System.ServiceModel.Channels.Binding binding = null;
if (!duplex)
binding = new WSHttpBinding()
{
SendTimeout = new TimeSpan(1, 0, 0, 0, 0),
ReceiveTimeout = new TimeSpan(1, 0, 0, 0, 0),
MaxReceivedMessageSize = 2147483647,
};
else binding = new WSDualHttpBinding()
{
SendTimeout = new TimeSpan(1, 0, 0, 0, 0),
ReceiveTimeout = new TimeSpan(1, 0, 0, 0, 0),
MaxReceivedMessageSize = 2147483647,
};
return binding;
}
#endregion
#region 添加服務
public string AddService(Type Interface, Type Class, string Name, string host, bool duplex)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
Name = Name,
C = Class,
I = Interface,
Host = host,
UseDuplex = duplex,
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class, string Name, int Port, bool duplex)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
Name = Name,
C = Class,
I = Interface,
Port = Port,
UseDuplex = duplex,
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class, string Name, bool duplex)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
Name = Name,
C = Class,
I = Interface,
UseDuplex = duplex,
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class, string Name, int port)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
Name = Name,
C = Class,
I = Interface,
Port = port
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class, string Name, string host)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
Name = Name,
C = Class,
I = Interface,
Host = host
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class, bool duplex)
{
WcfStruct wcf = new WcfStruct()
{
C = Class,
I = Interface,
UseDuplex = duplex,
};
list.Add(wcf);
return "添加服務成功!";
}
public string AddService(Type Interface, Type Class, string Name)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
Name = Name,
C = Class,
I = Interface,
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class, int Port)
{
string msg = "添加服務成功!";
WcfStruct wcf = new WcfStruct()
{
C = Class,
I = Interface,
Port = Port,
};
foreach (var wcf1 in list)
{
if (wcf1.Name == wcf.Name && !string.IsNullOrEmpty(wcf.Name))
{
return string.Format("添加WCF服務失敗,名為:{0}的服務已存在!多個WCF服務名字不允許重覆!", wcf.Name);
}
}
list.Add(wcf);
return msg;
}
public string AddService(Type Interface, Type Class)
{
WcfStruct wcf = new WcfStruct()
{
C = Class,
I = Interface,
};
list.Add(wcf);
return "添加服務成功!";
}
#endregion
#region 獲取所有服務
public List<WcfStruct> GetServiceList() =>list;
#endregion
#region 停止指定服務
public string StopServiceByName(string Name)
{
if (string.IsNullOrEmpty(Name))
{
return "停止指定服務必須提供服務名!";
}
foreach(var m in list)
{
if (m.Name == Name)
{
if(m.sh!=null && m.sh.State != CommunicationState.Closed)
{
m.sh.Close();
}
if (m.wsh != null && m.wsh.State != CommunicationState.Closed)
{
m.wsh.Close();
}
return "停止指定服務成功!服務名"+Name;
}
}
return "停止制定的服務錯誤服務名:"+Name;
}
#endregion
#region 啟動指定的服務
public string StartServiceByName(string Name)
{
if (string.IsNullOrEmpty(Name))
{
return "啟動指定服務必須提供服務名!";
}
string err = string.Empty;
try
{
for (int i = list.Count - 1; i >= 0; i--)
{
if (list[i].Name == Name)
{
if (list[i].sh.State != CommunicationState.Closed)
{
list[i].sh.Close();
}
string HostAddr = (!list[i].Host.Contains("http://")) ? "http://" + list[i].Host + "/" + Name : list[i].Host + "/" + Name;
ServiceHost sh = new ServiceHost(list[i].C, new Uri(HostAddr));
err += "服務地址:" + HostAddr + "\r\n";
sh.AddServiceEndpoint(list[i].I, InitBinding(list[i].UseDuplex), list[i].Name);
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
//HostAddr += "/wsdl";
behavior.HttpGetUrl = new Uri(HostAddr);
err += "元數據地址:" + HostAddr.ToString() + "\r\n";
sh.Description.Behaviors.Add(behavior);
sh.Description.Name = Name;
sh.Open();
list[i].sh = sh;
//if (list[0].UseWeb)
//{
// WebServiceHost webServiceHost = new WebServiceHost(list[i].C, new Uri(HostAddr));
// webServiceHost.Open();
// list[0].wsh = webServiceHost;
//}
return "啟動指定服務成功!服務名" + Name+"服務地址:"+HostAddr;
}
}
return "位置找到名為:" + Name + "的服務定義!";
}
catch(Exception ex)
{
return "啟動指定的服務錯誤:" + ex.Message;
}
}
#endregion
#region 啟動服務
/// <summary>
/// 啟動服務
/// </summary>
/// <param name="host">發佈地址</param>
/// <param name="err">返回消息</param>
public string Start()
{
string err = "啟動服務成功!\r\n";
string ip = getHost();
if (string.IsNullOrEmpty(ip))
{
err = "自動識別本機IP地址失敗!無法繼續創建服務!";
return err;
}
try
{
foreach (WcfStruct ws in list)
{
int potr=(ws.Port != 0 ? ws.Port : Port);
string host = (!string.IsNullOrEmpty(ws.Host)?ws.Host:ip+":"+potr);
string host1 =(!host.Contains("http://"))? "http://" + host: host;
string HostAddr = host1+"/"+(!string.IsNullOrEmpty(ws.Name)?ws.Name:ws.C.Name);
ServiceHost sh = new ServiceHost(ws.C, new Uri(HostAddr));
err += "服務地址:" + HostAddr + "\r\n";
sh.AddServiceEndpoint(ws.I, InitBinding(ws.UseDuplex),(!string.IsNullOrEmpty(ws.Name) ? ws.Name : ws.C.Name));
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri(HostAddr);
err += "元數據地址:" + HostAddr.ToString() + "\r\n";
sh.Description.Behaviors.RemoveAll<ServiceMetadataBehavior>();
sh.Description.Behaviors.Add(behavior);
sh.Description.Name = (!string.IsNullOrEmpty(ws.Name) ? ws.Name : ws.C.Name);
sh.Open();
ws.sh = sh;
ws.Host = host;
ws.Port = potr;
ws.Name = (!string.IsNullOrEmpty(ws.Name) ? ws.Name : ws.C.Name);
//if (ws.UseWeb)
//{
// WebServiceHost webServiceHost = new WebServiceHost(ws.C, new Uri(HostAddr));
// webServiceHost.Open();
// ws.wsh = webServiceHost;
// err += ws.wsh.Description.Endpoints[0].ListenUri.ToString();
//}
}
IsRunning = true;
return err;
}catch(Exception ex)
{
Stop();
IsRunning = false;
err = "啟動服務異常:" + ex.Message;
return err;
}
}
#endregion
#region 停止所有服務
/// <summary>
/// 停止Wcf服務
/// </summary>
/// <param name="err"></param>
public string Stop()
{
string err = "停止服務成功!";
try
{
foreach (WcfStruct ws in list)
{
if (ws.sh!=null&&ws.sh.State != CommunicationState.Closed)
{
ws.sh.Close();
}
if (ws.wsh != null&& ws.wsh.State != CommunicationState.Closed)
{
ws.wsh.Close();
}
}
list.Clear();
IsRunning = false;
}catch(Exception ex)
{
err = "停止服務發生異常:" + ex.Message;
}
return err;
}
#endregion
#region 取host
string getHost()
{
string hostname = Dns.GetHostName();
IPHostEntry He= Dns.GetHostEntry(hostname);
foreach (var m in He.AddressList)
{
if (m.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return m.ToString();
// return m.Address.ToString();
}
}
return "";
}
#endregion
}
/// <summary>
/// Wcf服務參數存儲結構類
/// </summary>
public class WcfStruct
{
internal ServiceHost sh { get; set; }
internal WebServiceHost wsh { get; set; }
internal string Name { get; set; }
internal string Host { get; set; }
internal int Port { get; set; }
internal Type C { get; set; }
internal Type I { get; set; }
internal bool UseDuplex { get; set; } = false;
internal bool UseWeb { get; set; } = false;
}
}
簡單調用實例代碼:
Gaofajin.Net.WcfRunerNew wcfRuner = new Gaofajin.Net.WcfRunerNew();
WriteLine(wcfRuner.AddService(typeof(IMessage), typeof(MessageSvr),"MessageSvr","http://localhost:9999",true));
WriteLine(wcfRuner.AddService(typeof(IService1), typeof(Service1),false));
WriteLine(wcfRuner.AddService(typeof(IService1), typeof(Service1)));
WriteLine(wcfRuner.Start());