Cross domain policy file over net.tcp for WCF servicehost and Silverlight 5

大城市里の小女人 提交于 2019-12-01 11:55:27

问题


I have a locally hosted WCF service and a silverlight 5 app that communicates with it. By default silverlight tries to obtain the cross domain policy file over HTTP when making calls to the WCF service. I need to change this so that the policy file is served over net.tcp port 943 instead.

I have setup a local tcp listener that serves up the policy file over port 943 and i have followed this technique whereby i make a dummy socket connection in order to obtain the policy file over tcp as it is only retrieved once per application lifetime. The tcp server is being hit as expected and i am getting SocketError property value as Success (though i must note, the first time i hit the tcp server after starting the listener, the result is always access denied).

From what i can tell, the policy file is either invalid as the silverlight application as still unable to connect or the above mentioned technique does not work with silverlight 5.

What i would like to know is if what i am doing is possible & im doing it correctly, otherwise if there is an alternative means to have the policy file successfully downloaded over tcp and removing the need for retrieving it over HTTP.

Thanks


回答1:


I wrote a long post about hosting silverlight in WPF - and using WCF with a http listener here:

How can I host a Silverlight 4 application in a WPF 4 application?

Now while not directly answering your question, it does show how to create a http version of the policy file.

I have also written something that serves up a policy listener over port 943, but I can't find where I posted the source - so I'll keep digging. As far as I remember though, silverlight does a cascade find of the policy file, if it doesn't get a connection on port 80, it'll then look on port 943.

I hope this is of some help somewhere.

Ok, here is the policy listener I had for net.TCP transport i.e. not HTTP based. I presume you have sorted this by now, sorry for the delay. It may well be of use to someone else now.

I was looking for the MS thing that said they cascade from HTTP to TCP, however, I can't, and therefore have to assume it was bunk and then changed.

Either way, if you call using a net.TCP service, and want a listener for it, this code should help:

#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


来源:https://stackoverflow.com/questions/15783086/cross-domain-policy-file-over-net-tcp-for-wcf-servicehost-and-silverlight-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!