2014-09-26 121 views
1

我一直在努力解决这个问题,所以真的希望有人有一些见解。将Silverlight客户端连接到SignalR服务器

我有一个控制台应用程序,它运行/托管我的signalR服务器。
我已经成功连接到它使用Web(JavaScript)客户端和Windows窗体客户端没有任何问题。

但是对于我的生活,我无法获得Silverlight客户端连接到它。起初,我对

等待Connection.Start

得到一个

'System.Security.SecurityException' 发生在Microsoft.Threading.Tasks错误();

我设法解决这个问题,强制发送clientaccesspolicy文件使用我在随机线程上找到的代码。

THREAD

但是连接仍然没有建立。状态通过连接,断开,连接关闭。

我在我的智慧结束为什么这不起作用。任何输入赞赏。下面的代码。

MainPage.xaml.cs 
public partial class MainPage : UserControl 
{ 
    private SignalRClient client; 

    public MainPage() 
    { 
     InitializeComponent(); 

     dataGrid1.ItemsSource = new ItemsCollection(); 

     client = new SignalRClient(); 
     client.RunAsync(); 

     Debug.WriteLine("Init Done"); 
    } 
} 

-

SignalRClient.cs 
public class SignalRClient 
{ 
    private HubConnection Connection { get; set; } 
    private IHubProxy HubProxy { get; set; } 

    const string url = "http://localhost:8080/"; 

    public SignalRClient() 
    { 

    } 

    public async void RunAsync() 
    { 
     Connection = new HubConnection(url, useDefaultUrl: true); 
     Connection.Closed += Connection_Closed; 
     Connection.StateChanged += ConnectionDidSomething; 

     HubProxy = Connection.CreateHubProxy("TickerHub"); 
     HubProxy.On<string>("receiveAllData", data => Debug.WriteLine("RECDATA={0}", data)); 

     try 
     { 
      await Connection.Start(); 
     } 
     catch (HttpClientException e) 
     { 
      Debug.WriteLine("Unable to connect to server.1 {0}", e.Message); 
      return; 
     } 
     catch (HttpRequestException e) 
     { 
      Debug.WriteLine("Unable to connect to server.2 {0}", e.Message); 
      return; 
     } 
    } 

-

Server 
class Program 
{ 
    static void Main(string[] args) 
    {    
     string url = "http://localhost:8080/"; 
     using (WebApp.Start(url)) 
     { 
      Console.WriteLine("SignalR server running on {0}", url); 
      Console.ReadLine(); 
     }    

     Console.ReadLine(); 
    } 
} 

class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     Console.WriteLine("Configuration"); 

     //Tried this approach too 
     /*app.Map("/signalr", map => 
     {     
      map.UseCors(CorsOptions.AllowAll); 
      var hubConfiguration = new HubConfiguration 
      { 
       EnableJSONP = true 
      }; 
      map.RunSignalR(hubConfiguration); 
     });*/ 

     app.UseCors(CorsOptions.AllowAll); 
     app.MapSignalR<ClientAccessPolicyConnection>("/clientaccesspolicy.xml"); 
    } 
} 

-

TickerHub.cs 
public class TickerHub : Hub 
{ 
    public override Task OnConnected() 
    { 
     string connectionID = Context.ConnectionId; 
     Console.WriteLine("New Connection:" + connectionID); 

     InitNewClient(connectionID); 

     return base.OnConnected();    
    } 

    //send all data to newly connected client 
    public void InitNewClient(string connectionID) 
    { 
    } 

    //client requested all data 
    public void GetAllData() 
    { 
     Console.WriteLine("Get Data Triggered");   

     Clients.All.receiveAllData("TESTING123"); 
    } 

} 

回答

1

我想通了!希望这有助于未来的人。

它很简单。这是你的启动类配置方法所需要的。 下面是发送clientaccesspolicy.xml所需的代码。

class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     // Branch the pipeline here for requests that start with "/signalr" 
     app.Map("/signalr", map => 
     { 
      // Setup the CORS middleware to run before SignalR. 
      // By default this will allow all origins. You can 
      // configure the set of origins and/or http verbs by 
      // providing a cors options with a different policy. 
      map.UseCors(CorsOptions.AllowAll); 
      var hubConfiguration = new HubConfiguration 
      { 
       // You can enable JSONP by uncommenting line below. 
       // JSONP requests are insecure but some older browsers (and some 
       // versions of IE) require JSONP to work cross domain 
       EnableJSONP = true 
      }; 
      // Run the SignalR pipeline. We're not using MapSignalR 
      // since this branch already runs under the "/signalr" 
      // path. 
      map.RunSignalR(hubConfiguration); 
     }); 

     app.UseCors(CorsOptions.AllowAll); 
     app.MapSignalR<ClientAccessPolicyConnection>("/clientaccesspolicy.xml"); 
    } 
} 

-

public class ClientAccessPolicyConnection : PersistentConnection 
{ 
    public override Task ProcessRequest(Microsoft.AspNet.SignalR.Hosting.HostContext context) 
    { 
     string[] urlArray = context.Request.Url.ToString().Split('/'); 

     string path = urlArray[urlArray.Length - 1]; 

     if (path.Equals("clientaccesspolicy.xml", StringComparison.InvariantCultureIgnoreCase)) 
     { 
      //Convert policy to byteArray 
      var array = Encoding.UTF8.GetBytes(ClientAccessPolicy); 
      var segment = new ArraySegment<byte>(array); 

      //Write response 
      context.Response.ContentType = "text/xml"; 
      context.Response.Write(segment); 

      //Return empty task to escape from SignalR's default Connection/Transport checks. 
      return EmptyTask; 
     } 

     return EmptyTask; 
    } 

    private static readonly Task EmptyTask = MakeTask<object>(null); 

    public static Task<T> MakeTask<T>(T value) 
    { 
     var tcs = new TaskCompletionSource<T>(); 
     tcs.SetResult(value); 
     return tcs.Task; 
    } 

    public static readonly string ClientAccessPolicy = 
     "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 
       + "<access-policy>" 
        + "<cross-domain-access>" 
        + "<policy>" 
         + "<allow-from http-request-headers=\"*\">" 
          + "<domain uri=\"*\"/>" 
         + "</allow-from>" 
         + "<grant-to>" 
          + "<resource path=\"/\" include-subpaths=\"true\"/>" 
         + "</grant-to>" 
        + "</policy>" 
       + "</cross-domain-access>" 
       + "</access-policy>"; 
}