很难找到与https一起使用的XMLRPC.net库的信息。
唯一可以设置“https”网址的文档在这里:http://xml-rpc.net/faq/xmlrpcnetfaq-2-5-0.html#2.3但是它并没有准确解释如何正确设置。
尝试下载http://xmlrpcnet.googlecode.com/files/xml-rpc.net.2.5.0.zip中提供的样本,我尝试了这个:
StateNameServer解决方案的client.cs文件中的更改:
IStateName svr = (IStateName)Activator.GetObject(
typeof(IStateName), "https://localhost:5678/statename.rem");
服务器代码是什么样的
IDictionary props = new Hashtable();
props["name"] = "MyHttpChannel";
props["port"] = 5678;
HttpChannel channel = new HttpChannel(
props,
null,
new XmlRpcServerFormatterSinkProvider()
);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(StateNameServer),
"statename.rem",
WellKnownObjectMode.Singleton);
当尝试使用HTTPS联系服务器时,客户端显然会丢弃异常,因为我不知道如何配置它。无论如何,有人可以帮忙吗?我应该寻找什么样的东西?
非常感谢!
答案 0 :(得分:3)
首先,我要热烈感谢Charles Cook对此问题的帮助以及开发XMLRPC.NET。
其次,此示例基于可在此处下载的XMLRPC.NET StateNameServer示例: http://xml-rpc.net/download.html
所以这是解决方案:
<强> 1。生成或获取[自签名]证书(例如,使用makecert.exe)
<强> 2。将此证书添加到服务器配置中,并使用httpcfg.exe或其他工具(如HttpSysConfig(开源) 指定要与XMLRPC.NET服务器一起使用的端口(在本例中为5678) p>
第3。使用以下代码实现XMLRPC.NET服务器:
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using CookComputing.XmlRpc;
using System.Net;
using System.IO;
public class _
{
static void Main(string[] args)
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("https://127.0.0.1:5678/");
listener.Start();
while (true)
{
HttpListenerContext context = listener.GetContext();
ListenerService svc = new StateNameService();
svc.ProcessRequest(context);
}
Console.WriteLine("Press <ENTER> to shutdown");
Console.ReadLine();
}
}
public class StateNameService : ListenerService
{
[XmlRpcMethod("examples.getStateName")]
public string GetStateName(int stateNumber)
{
if (stateNumber < 1 || stateNumber > m_stateNames.Length)
throw new XmlRpcFaultException(1, "Invalid state number");
return m_stateNames[stateNumber - 1];
}
string[] m_stateNames
= { "Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Lousiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississipi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma",
"Oregon", "Pennsylviania", "Rhose Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming" };
}
public abstract class ListenerService : XmlRpcHttpServerProtocol
{
public virtual void ProcessRequest(HttpListenerContext RequestContext)
{
try
{
IHttpRequest req = new ListenerRequest(RequestContext.Request);
IHttpResponse resp = new ListenerResponse(RequestContext.Response);
HandleHttpRequest(req, resp);
RequestContext.Response.OutputStream.Close();
}
catch (Exception ex)
{
// "Internal server error"
RequestContext.Response.StatusCode = 500;
RequestContext.Response.StatusDescription = ex.Message;
}
}
}
public class ListenerRequest : CookComputing.XmlRpc.IHttpRequest
{
public ListenerRequest(HttpListenerRequest request)
{
this.request = request;
}
public Stream InputStream
{
get { return request.InputStream; }
}
public string HttpMethod
{
get { return request.HttpMethod; }
}
private HttpListenerRequest request;
}
public class ListenerResponse : CookComputing.XmlRpc.IHttpResponse
{
public ListenerResponse(HttpListenerResponse response)
{
this.response = response;
}
string IHttpResponse.ContentType
{
get { return response.ContentType; }
set { response.ContentType = value; }
}
TextWriter IHttpResponse.Output
{
get { return new StreamWriter(response.OutputStream); }
}
Stream IHttpResponse.OutputStream
{
get { return response.OutputStream; }
}
int IHttpResponse.StatusCode
{
get { return response.StatusCode; }
set { response.StatusCode = value; }
}
string IHttpResponse.StatusDescription
{
get { return response.StatusDescription; }
set { response.StatusDescription = value; }
}
private HttpListenerResponse response;
}
public class StateNameServer : MarshalByRefObject, IStateName
{
public string GetStateName(int stateNumber)
{
if (stateNumber < 1 || stateNumber > m_stateNames.Length)
throw new XmlRpcFaultException(1, "Invalid state number");
return m_stateNames[stateNumber-1];
}
public string GetStateNames(StateStructRequest request)
{
if (request.state1 < 1 || request.state1 > m_stateNames.Length)
throw new XmlRpcFaultException(1, "State number 1 invalid");
if (request.state2 < 1 || request.state2 > m_stateNames.Length)
throw new XmlRpcFaultException(1, "State number 1 invalid");
if (request.state3 < 1 || request.state3 > m_stateNames.Length)
throw new XmlRpcFaultException(1, "State number 1 invalid");
string ret = m_stateNames[request.state1-1] + " "
+ m_stateNames[request.state2-1] + " "
+ m_stateNames[request.state3-1];
return ret;
}
string[] m_stateNames
= { "Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Lousiana", "Maine", "Maryland", "Massachusetts",
"Michigan", "Minnesota", "Mississipi", "Missouri", "Montana",
"Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma",
"Oregon", "Pennsylviania", "Rhose Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming" };
}
<强> 4。使用以下代码实现XMLRPC.NET客户端(代码还会创建新的X509客户端证书)
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using CookComputing.XmlRpc;
using System.Net;
using System.Security.Cryptography.X509Certificates;
class _
{
public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
{
public TrustAllCertificatePolicy() { }
public bool CheckValidationResult(ServicePoint sp,
X509Certificate cert,
WebRequest req,
int problem)
{
return true;
}
}
static void Main(string[] args)
{
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
IStateName proxy = XmlRpcProxyGen.Create<IStateName>();
XmlRpcClientProtocol cp = (XmlRpcClientProtocol)proxy;
cp.Url = "https://127.0.0.1:5678/";
cp.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(@"C:\path\to\your\certificate\file\my.cer"));
cp.KeepAlive = false;
//cp.Expect100Continue = false;
//cp.NonStandard = XmlRpcNonStandard.All;
string stateName = ((IStateName)cp).GetStateName(13);
}
}
当然,我不会在这里给出ServerStateName的接口实现,但你可以使用顶部的下载链接在示例文件中找到它。
备注:
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy()
;将允许服务器实现接受您自己生成的自签名证书。我认为证书颁发机构颁发的证书不需要这样做。
如果您发现任何可以改进的内容并且不正确,我们将不胜感激。
答案 1 :(得分:2)
使用XmlRpcProxyGen.Create创建客户端代理,指定https url(您的接口应从IXmlRpcProxy派生)。如果您需要提供客户端证书,则代理具有ClientCertificates属性,该属性的使用方式与System.Net.HttpWebRequest类中的相应属性相同。
我不认为Remoting可以支持HTTPS。您可以按照XML-RPC.NET FAQ中的说明使用HttpListener,但您需要配置证书,例如,如blog
中所述答案 2 :(得分:1)
好文章!帮助了我很多。 但是第1项和第2项花了我一天才弄明白。所以这是我的经历:
netsh http add sslcert ipport=192.168.111.195:4022 certhash=c8973a86141a7a564a6f509d1ecfea326a1852a2 appid={0a582a74-fc2d-476c-9281-c73b2e4bfb26}
中运行以下字符串,其中'ipport'是将用于ssl连接的ip / port对; 'certhash'是证书哈希(您在上一步中创建的开放证书 - &gt;转到详细信息 - &gt;查找Thumbprint); 'appid'可以是任何。如果您在HttpListener网址中指定“https”,则此类会自动查找绑定证书。