在工作中经常使用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());