The clientaccesspolicy.xml won't come into play, as this is sockets. If you think about it, you are never guaranteed to have a web server on the same machine as your socket server. When you consider port *all* calls are "cross domain" conceptually.
So, what the Silverlight team did in Beta 2 was require, for 100% of the scenarios, a policy server running on port 943 which serves up a slightly different crossdomain xml file.
There's a brief description on Tim Heuer's blog.
Here's an example policy file:
<?xml version="1.0" encoding ="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*" />
</allow-from>
<grant-to>
<socket-resource port="4532" protocol="tcp" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
And here's code that serves it up from a console app (taken from a chat application demo I did):
(Program.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PolicyServer
{
class Program
{
static void Main(string[] args)
{
PolicySocketServer server = new PolicySocketServer();
server.StartSocketServer();
}
}
}
(PolicySocketServer.cs - shamelessly snagged from the URL below)
// Code from http://weblogs.asp.net/dwahlin/archive/2008/06/08/creating-a-silverlight-2-client-access-policy-socket-server.aspx
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Reflection;
using System.Configuration;
namespace PolicyServer
{
class PolicySocketServer
{
TcpListener _Listener = null;
TcpClient _Client = null;
static ManualResetEvent _TcpClientConnected = new ManualResetEvent(false);
const string _PolicyRequestString = "<policy-file-request/>";
int _ReceivedLength = 0;
byte[] _Policy = null;
byte[] _ReceiveBuffer = null;
private void InitializeData()
{
string policyFile = ConfigurationManager.AppSettings["PolicyFilePath"];
using (FileStream fs = new FileStream(policyFile, FileMode.Open))
{
_Policy = new byte[fs.Length];
fs.Read(_Policy, 0, _Policy.Length);
}
_ReceiveBuffer = new byte[_PolicyRequestString.Length];
}
public void StartSocketServer()
{
InitializeData();
try
{
//Using TcpListener which is a wrapper around a Socket
//Allowed port is 943 for Silverlight sockets policy data
_Listener = new TcpListener(IPAddress.Any, 943);
_Listener.Start();
Console.WriteLine("Policy server listening...");
while (true)
{
_TcpClientConnected.Reset();
Console.WriteLine("Waiting for client connection...");
_Listener.BeginAcceptTcpClient(new AsyncCallback(OnBeginAccept), null);
_TcpClientConnected.WaitOne(); //Block until client connects
}
}
catch (Exception exp)
{
LogError(exp);
}
}
private void OnBeginAccept(IAsyncResult ar)
{
_Client = _Listener.EndAcceptTcpClient(ar);
_Client.Client.BeginReceive(_ReceiveBuffer, 0, _PolicyRequestString.Length, SocketFlags.None,
new AsyncCallback(OnReceiveComplete), null);
}
private void OnReceiveComplete(IAsyncResult ar)
{
try
{
_ReceivedLength += _Client.Client.EndReceive(ar);
//See if there's more data that we need to grab
if (_ReceivedLength < _PolicyRequestString.Length)
{
//Need to grab more data so receive remaining data
_Client.Client.BeginReceive(_ReceiveBuffer, _ReceivedLength,
_PolicyRequestString.Length - _ReceivedLength,
SocketFlags.None, new AsyncCallback(OnReceiveComplete), null);
return;
}
//Check that <policy-file-request/> was sent from client
string request = System.Text.Encoding.UTF8.GetString(_ReceiveBuffer, 0, _ReceivedLength);
if (StringComparer.InvariantCultureIgnoreCase.Compare(request, _PolicyRequestString) != 0)
{
//Data received isn't valid so close
_Client.Client.Close();
return;
}
//Valid request received....send policy data
_Client.Client.BeginSend(_Policy, 0, _Policy.Length, SocketFlags.None,
new AsyncCallback(OnSendComplete), null);
}
catch (Exception exp)
{
_Client.Client.Close();
LogError(exp);
}
_ReceivedLength = 0;
_TcpClientConnected.Set(); //Allow waiting thread to proceed
}
private void OnSendComplete(IAsyncResult ar)
{
try
{
_Client.Client.EndSendFile(ar);
}
catch (Exception exp)
{
LogError(exp);
}
finally
{
//Close client socket
_Client.Client.Close();
}
}
private void LogError(Exception exp)
{
string appFullPath = Assembly.GetCallingAssembly().Location;
string logPath = appFullPath.Substring(0, appFullPath.LastIndexOf("\\")) + ".log";
StreamWriter writer = new StreamWriter(logPath, true);
try
{
writer.WriteLine(logPath,
String.Format("Error in PolicySocketServer: "
+ "{0} \r\n StackTrace: {1}", exp.Message, exp.StackTrace));
}
catch { }
finally
{
writer.Close();
}
}
}
}
Pete
If your question was answered, please mark the response as the answer.
Silverlight.net Moderator
MVP: Visual Developer - Client Application Development
POKE 53280,0 - My Blog