最近要针对Flash和Silverlight写一些Socket通讯的用例,由于这两者的Socket出于安全性考虑都需要一个Prolicy Server.在网上找了一下发现都只是代码没有相关程序直接用,于是就用Beetle实现了Flash和Silverlight的policy Server,使用的时候根据情况配置开启Flash或Silverlight.如果需要两者同时可以打开,以下简单地介绍实现过程。
首先我们必须知道Flash和Silverlight信任文件是怎样的.
Flash
<cross-domain-policy> <site-control permitted-cross-domain-policies="master-only"/> <allow-access-from domain="*" to-ports="*" secure="false"/> </cross-domain-policy>
Silverlight
<?xml version="1.0" encoding="utf-8" ?> <access-policy> <cross-domain-access> <policy> <allow-from> <domain uri="*"/> </allow-from> <grant-to> <socket-resource port="4502-4534" protocol="tcp"/> </grant-to> </policy> </cross-domain-access> </access-policy>
两者的工作方式分别是Flash请求843端口,而Silverlight则是943;服务端在接收请求信息,根据不情况返回实际信任XML信息即可。以下是基于Beetle的简单服务实现。
class Program:ServerBase
{
static void Main(string[] args)
{
Console.WriteLine("Silverlight and Flash Prolicy Server Copyright @ Kender 2012");
Console.WriteLine("website:www.ikender.com");
Console.WriteLine("email:[email protected]");
Console.WriteLine("qq:28304340");
Beetle.TcpUtils.Setup("beetle");
if (ProlicySection.Instance.FlashEnabled)
{
Program flashprolicy = new Program();
flashprolicy.Type = ProlicyType.Flash;
flashprolicy.Open(ProlicySection.Instance.FlashPort);
Console.WriteLine("Start Flash Prolicy Server @" + ProlicySection.Instance.FlashPort);
}
if (ProlicySection.Instance.SLEnabled)
{
Program flashprolicy = new Program();
flashprolicy.Type = ProlicyType.Silverlight;
flashprolicy.Open(ProlicySection.Instance.SLPort);
Console.WriteLine("Start Silverlight Prolicy Server @" + ProlicySection.Instance.SLPort);
}
Console.Read();
}
public ProlicyType Type
{
get;
set;
}
public enum ProlicyType
{
Flash,
Silverlight
}
protected override void OnConnected(object sender, ChannelEventArgs e)
{
base.OnConnected(sender, e);
e.Channel.EnabledSendCompeletedEvent = true;
e.Channel.SendMessageCompleted = (o, m) => { m.Channel.Dispose(); };
Console.WriteLine("{0} connected!", e.Channel.EndPoint);
}
protected override void OnDisposed(object sender, ChannelDisposedEventArgs e)
{
base.OnDisposed(sender, e);
Console.WriteLine("{0} disposed!", e.Channel.EndPoint);
}
protected override void OnError(object sender, ChannelErrorEventArgs e)
{
base.OnError(sender, e);
Console.WriteLine("{0} error {1}!", e.Channel.EndPoint,e.Exception.Message);
}
protected override void OnReceive(object sender, ChannelReceiveEventArgs e)
{
base.OnReceive(sender, e);
Console.WriteLine(e.Channel.Coding.GetString(e.Data.Array, e.Data.Offset, e.Data.Count));
StringMessage message = new StringMessage();
if (Type == ProlicyType.Flash)
{
message.Value = Utils.GetFlashPolicy();
}
else
{
message.Value = Utils.GetSLPolicy();
}
e.Channel.Send(message);
}
}
Program对象继承ServerBase然后重写几个相关方法,在OnReceive事件里根据当前Server的不同类型进行一个信任文件输出即可.Utils类主要封装信任文件信息的读取,代码如下:
class Utils
{
static string mSLPolicy = null;
static string mFlashPolicy = null;
public static string GetSLPolicy()
{
if (mSLPolicy == null)
{
string filename = AppDomain.CurrentDomain.BaseDirectory + "SLPolicy.xml";
using (System.IO.StreamReader reader = new System.IO.StreamReader(filename, Encoding.UTF8))
{
mSLPolicy= reader.ReadToEnd();
}
}
return mSLPolicy;
}
public static string GetFlashPolicy()
{
if (mFlashPolicy == null)
{
string filename = AppDomain.CurrentDomain.BaseDirectory + "FlashPolicy.xml";
using (System.IO.StreamReader reader = new System.IO.StreamReader(filename, Encoding.UTF8))
{
mFlashPolicy= reader.ReadToEnd() + "\0";
}
}
return mFlashPolicy;
}
}
这样一个同时支持Flash和Silverlight的policy Server就完成了,是不是很简单。