ポート範囲 4502 ~ 4534 で TCP 接続を確立しようとすると、Silverlight は最初にポート 943 にリクエストを送信して、クライアント アクセス ポリシー ファイルのコンテンツを取得します。http://localhost.myserivce.com のファイルは読み取られません。 /clientaccesspolicy.xml、これは HTTP 要求専用であるためです。TCP ポート 943 でリッスンするようにサーバーを構成する必要があります。要求文字列<policy-file-request/>
が xml ファイルの内容と同じであることを期待して応答します。
以下のコードは基本的な実装を示しています。ポート 943 を使用してローカルの IPEndPoint に渡す必要があります。
public class SocketPolicyServer
{
private const string m_policyRequestString = "<policy-file-request/>";
private string m_policyResponseString;
private TcpListener m_listener;
bool _started = false;
public SocketPolicyServer()
{
m_policyResponseString = File.ReadAllText("path/to/clientaccesspolicy.xml");
}
public void Start(IPEndPoint endpoint)
{
m_listener = new TcpListener(endpoint);
m_listener.Start();
_started = true;
m_listener.BeginAcceptTcpClient(HandleClient, null);
}
public event EventHandler ClientConnected;
public event EventHandler ClientDisconnected;
private void HandleClient(IAsyncResult res)
{
if(_started)
{
try
{
TcpClient client = m_listener.EndAcceptTcpClient(res);
m_listener.BeginAcceptTcpClient(HandleClient, null);
this.ProcessClient(client);
}
catch(Exception ex)
{
Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
}
}
}
public void Stop()
{
_started = false;
m_listener.Stop();
}
public void ProcessClient(TcpClient client)
{
try
{
if(this.ClientConnected != null)
this.ClientConnected(this, EventArgs.Empty);
StreamReader reader = new StreamReader(client.GetStream(), Encoding.UTF8);
char[] buffer = new char[m_policyRequestString.Length];
int read = reader.Read(buffer, 0, buffer.Length);
if(read == buffer.Length)
{
string request = new string(buffer);
if(StringComparer.InvariantCultureIgnoreCase.Compare(request, m_policyRequestString) == 0)
{
StreamWriter writer = new StreamWriter(client.GetStream());
writer.Write(m_policyResponseString);
writer.Flush();
}
}
}
catch(Exception ex)
{
Trace.TraceError("SocketPolicyServer : {0}", ex.Message);
}
finally
{
client.GetStream().Close();
client.Close();
if(this.ClientDisconnected != null)
this.ClientDisconnected(this, EventArgs.Empty);
}
}
}