📄 xmlrpcpings.cs
字号:
//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
// Copyright (c) Telligent Systems Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;
using CommunityServer.Components;
using CommunityServer.Configuration;
using CookComputing.XmlRpc;
namespace CommunityServer.Blogs.Components
{
[XmlRpcMissingMapping(MappingAction.Ignore)]
public struct PingResult
{
public XmlRpcBoolean flerror;
public string message;
}
/// <summary>
/// Enables pinging of community blogging sites such as weblogs.com after the blog is updated.
/// </summary>
[Serializable]
public class XmlRpcPings : XmlRpcClientProtocol
{
#region Private Fields
private int settingsID;
private WeblogPost post = null;
private CSContext context = null;
private Weblog weblog { get { return post.Weblog; } }
#endregion
public XmlRpcPings(int settingsID, WeblogPost wp, CSContext ctx)
{
this.settingsID = settingsID;
this.post = wp;
this.context = ctx;
this.UserAgent = CSRequest.UserAgent;
this.Timeout = 60000;
// This improves compatibility with XML-RPC servers that do not fully comply with the XML-RPC specification.
this.NonStandard = XmlRpcNonStandard.All;
// Use a proxy server if one has been configured
CSConfiguration config = CSConfiguration.GetConfig();
if (config.ProxyHost != string.Empty)
{
WebProxy proxy = new WebProxy(config.ProxyHost, config.ProxyPort);
if (config.ProxyBypassList != string.Empty)
proxy.BypassList = config.ProxyBypassList.Split(',');
proxy.BypassProxyOnLocal = config.ProxyBypassOnLocal;
if (config.ProxyUsername != string.Empty)
proxy.Credentials = new NetworkCredential(config.ProxyUsername, config.ProxyPassword);
this.Proxy = proxy;
}
}
public bool CanPing
{
get { return (weblog != null && weblog.EnablePings && weblog.PingUrls != null && weblog.PingUrls.Length > 0); }
}
/// <summary>
/// Each ping has taken up to a minute to complete. This overload of SendPings enables
/// SendPings to be executed on a seperate thread.
/// </summary>
/// <param name="useBackGroundThread">Should this operation happen on a new thread</param>
public static void SendPings(WeblogPost wp, bool useBackGroundThread)
{
CSContext cntx = CSContext.Current;
XmlRpcPings pinger = new XmlRpcPings(cntx.SettingsID, wp, cntx);
if (useBackGroundThread)
{
ManagedThreadPool.QueueUserWorkItem(new WaitCallback(pinger.SendPings));
}
else
{
pinger.SendPings();
}
}
public void SendPings(object state)
{
// Create new Context
CSContext.Create(this.settingsID);
SendPings();
}
public void SendPings()
{
//Can we proceed?
if (!CanPing)
return;
// Gather information to pass to ping service(s)
string name = weblog.Name;
string url = context.HostPath + BlogUrls.Instance().HomePage(weblog.ApplicationKey);
string feedUrl = "";
if (weblog.EnableRss)
feedUrl = context.HostPath + BlogUrls.Instance().Rss(weblog.ApplicationKey);
else if (weblog.EnableAtom)
feedUrl = context.HostPath + BlogUrls.Instance().Atom(weblog.ApplicationKey);
// Not supporting RssPing for now until we get more info about spec.
/*
string postTitle = post.Subject;
string postUrl = BlogUrls.Instance().Post(post);
string postFeedUrl = BlogUrls.Instance().RssPost(weblog.ApplicationKey, post.PostID);
string postCategories = "";
if (post.HasCategories)
postCategories = post.Categories.GetValue(0) as string;
*/
// Use site setting unless indiv blog has overriden the setting
string[] pingUrls = WeblogConfiguration.Instance().DefaultPingServices;
if (weblog.PingUrls != null && weblog.PingUrls.Length > 0)
pingUrls = weblog.PingUrls;
if (pingUrls == null || pingUrls.Length == 0)
return;
foreach (string pingUrl in pingUrls)
{
if (!Globals.IsNullorEmpty(pingUrl))
{
this.Url = pingUrl;
bool result = false;
string errorMessage = "";
PingType requestedPingType = PingType.Auto;
PingType actualPingType = PingType.Auto;
object cachedPingType = CSCache.Get(CacheKey(pingUrl));
if (cachedPingType != null)
requestedPingType = (PingType)cachedPingType;
// Not supporting RssPing for now until we get more info about spec
/*
if (requestedPingType == PingType.Auto || requestedPingType == PingType.RssPing)
{
try
{
PingResult response = RssPing(name, url, feedUrl, postTitle, postUrl, postCategories, postFeedUrl);
if (response.flerror == null || response.flerror == false)
{
result = true;
actualPingType = PingType.RssPing;
}
}
catch (CookComputing.XmlRpc.XmlRpcException ex)
{
errorMessage = ex.Message;
}
catch (System.Exception ex)
{
errorMessage = ex.Message;
}
}
*/
if ((requestedPingType == PingType.Auto && !result) || requestedPingType == PingType.ExtendedPing)
{
try
{
PingResult response = ExtendedPing(name, url, feedUrl);
if (response.flerror != null && response.flerror == true)
{
if (Globals.IsNullorEmpty(response.message))
errorMessage = "Remote weblogUpdates.extendedPing service indicated an error but provided no error message.";
else
errorMessage = response.message;
}
else
{
result = true;
actualPingType = PingType.ExtendedPing;
}
}
catch (CookComputing.XmlRpc.XmlRpcException ex)
{
errorMessage = ex.Message;
}
catch (System.Exception ex)
{
errorMessage = ex.Message;
}
}
if ((requestedPingType == PingType.Auto && !result) || requestedPingType == PingType.BasicPing)
{
try
{
PingResult response = BasicPing(name, url);
if (response.flerror != null && response.flerror == true)
{
if (Globals.IsNullorEmpty(response.message))
errorMessage = "Remote weblogUpdates.ping service indicated an error but provided no error message.";
else
errorMessage = response.message;
}
else
{
result = true;
actualPingType = PingType.BasicPing;
}
}
catch (CookComputing.XmlRpc.XmlRpcException ex)
{
errorMessage = ex.Message;
}
catch (System.Exception ex)
{
errorMessage = ex.Message;
}
}
// If the requested ping type was Auto, cache the actual ping type used for this url for next time
if (requestedPingType == PingType.Auto)
CSCache.Insert(CacheKey(pingUrl), actualPingType, 7 * CSCache.DayFactor);
// Log succcess or failure to EventLog
if (result)
{
string message = String.Format("Weblog Ping sent to {0} for PostID {1}.", pingUrl, post.PostID);
EventLogs.Info(message, "Weblogs", 303, CSContext.Current.SettingsID);
}
else
{
string message = String.Format("Weblog Ping attempt to the url [{0}] failed for PostID {1}. Error message returned was: {2}.", pingUrl, post.PostID, errorMessage);
EventLogs.Warn(message, "Weblogs", 303, CSContext.Current.SettingsID);
}
}
}
}
private string CacheKey(string url)
{
return string.Format("PingService:PingType:{0}", url);
}
[XmlRpcMethod("weblogUpdates.ping")]
public PingResult BasicPing(string name, string url)
{
return (PingResult)Invoke("BasicPing", new Object[]{ name, url });
}
[XmlRpcMethod("weblogUpdates.extendedPing")]
public PingResult ExtendedPing(string name, string url, string feedUrl)
{
return (PingResult)Invoke("ExtendedPing", new Object[]{ name, url, url, feedUrl });
}
[XmlRpcMethod("weblogUpdates.rssPing")]
public PingResult RssPing(string name, string url, string feedUrl, string postTitle, string postUrl, string postCategories, string postFeedUrl)
{
return (PingResult)Invoke("RssPing", new Object[]{ name, url, feedUrl, postTitle, postUrl, postCategories, postFeedUrl });
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -