我有一个本地托管的WCF服务和一个与之通信的silverlight 5应用程序。默认情况下,silverlight在调用WCF服务时尝试通过HTTP获取跨域策略文件。我需要更改此设置,以便通过net.tcp端口943提供策略文件。
我已经设置了一个本地tcp监听器,通过端口943提供策略文件,我有followed this technique,我建立了一个虚拟套接字连接,以便通过tcp获取策略文件,因为它只检索一次应用寿命。正在按预期命中tcp服务器,我的SocketError
属性值为Success
(虽然我必须注意,我在启动监听器后第一次点击tcp服务器时,结果始终是拒绝访问)。
据我所知,策略文件无效,因为Silverlight应用程序仍然无法连接或上述技术无法与silverlight 5一起使用。
我想知道的是,如果我正在做的事情是可能的&我正确地做了,否则如果有另一种方法可以通过tcp成功下载策略文件,并且无需通过HTTP检索它。
由于
答案 0 :(得分:1)
我写了一篇关于在WPF中托管silverlight的长篇文章 - 并在这里使用带有http监听器的WCF:
How can I host a Silverlight 4 application in a WPF 4 application?
现在,虽然没有直接回答您的问题,但它确实显示了如何创建策略文件的http版本。
我还写了一些通过端口943提供策略监听器的东西,但我找不到我发布源的位置 - 所以我会继续挖掘。据我记得,Silverlight会对策略文件进行级联查找,如果它没有在端口80上获得连接,那么它将在端口943上查找。
我希望这对某些地方有所帮助。
好的,这是我对net.TCP传输的策略监听器,即不是基于HTTP的。我认为你现在已经对它进行了排序,对不起延迟了。它现在可能对其他人有用。
我一直在寻找那些说他们从HTTP级联到TCP的MS,然而,我不能,因此不得不假设它是下铺然后改变。
无论哪种方式,如果你使用net.TCP服务进行调用,并希望有一个监听器,这段代码应该有所帮助:
#region "Policy Listener"
// This is a simple policy listener
// that provides the cross domain policy file for silverlight applications
// this provides them with a network access policy
public class SocketPolicyListener
{
private TcpListener listener = null;
private TcpClient Client = null;
byte[] Data;
private NetworkStream netStream = null;
private string listenaddress = "";
// This could be read from a file on the disk, but for now, this gives the silverlight application
// the ability to access any domain, and all the silverlight ports 4502-4534
string policyfile = "<?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>";
// the request that we're expecting from the client
private string _policyRequestString = "<policy-file-request/>";
// Listen for our clients to connect
public void Listen(string ListenIPAddress)
{
listenaddress = ListenIPAddress;
if (listener == null)
{
listener = new TcpListener(IPAddress.Parse(ListenIPAddress), 943);
// Try and stop our clients from lingering, keeping the socket open:
LingerOption lo = new LingerOption(true, 1);
listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger,lo);
}
listener.Start();
WaitForClientConnect();
}
private void WaitForClientConnect()
{
listener.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), listener);
}
public void StopPolicyListener()
{
if (Client.Connected)
{
// Should never reach this point, as clients
// are closed if they request the policy
// only clients that open the connection and
// do not submit a policy request will remain unclosed
Client.Close();
}
listener.Stop();
}
public void RestartPolicyListener()
{
listener.Start();
}
// When a client connects:
private void OnClientConnected(IAsyncResult ar)
{
if (ar.IsCompleted)
{
// Get the listener that handles the client request.
TcpListener listener = (TcpListener)ar.AsyncState;
// End the operation and display the received data on
// the console.
Client = listener.EndAcceptTcpClient(ar);
// Try and stop our clients from lingering, keeping the socket open:
LingerOption lo = new LingerOption(true, 1);
Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
// Set our receive callback
Data = new byte[1024];
netStream = Client.GetStream();
netStream.BeginRead(Data, 0, 1024, ReceiveMessage, null);
}
WaitForClientConnect();
}
// Read from clients.
public void ReceiveMessage(IAsyncResult ar)
{
int bufferLength;
try
{
bufferLength = Client.GetStream().EndRead(ar);
// Receive the message from client side.
string messageReceived = Encoding.ASCII.GetString(Data, 0, bufferLength);
if (messageReceived == _policyRequestString)
{
// Send our policy file, as it's been requested
SendMessage(policyfile);
// Have to close the connection or the
// silverlight client will wait around.
Client.Close();
}
else
{
// Continue reading from client.
Client.GetStream().BeginRead(Data, 0, Data.Length, ReceiveMessage, null);
}
}
catch (Exception ex)
{
throw new Exception(Client.Client.RemoteEndPoint.ToString() + " is disconnected.");
}
}
// Send the message.
public void SendMessage(string message)
{
try
{
byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(message);
//Client.Client.Send(bytesToSend,SocketFlags.None);
Client.GetStream().Write(bytesToSend,0, bytesToSend.Length);
Client.GetStream().Flush();
}
catch (Exception ex)
{
throw ex;
}
}
}
#endregion