2014-02-13 3 views
1

У меня есть приложение SignalR в двух частях. У меня есть базовые сообщения, идущие туда и обратно между MVC-приложением (SignalR Server) и службой Windows (SignalR Client). Служба Windows находится на внутренней машине, на которой есть база данных AdventureWork2012. Управление желает, чтобы клиент службы Windows - SignalR запросил базу данных и отправил обратно DataSet через SignalR. Может ли SignalR передавать данные? Я получаю исключение «Недопустимый URI: строка Uri слишком длинная». в журнале событий, когда я вызываю метод сервера.SignalR Могу ли я передать DataSet

Вот MVC сервер-концентратор:

public class AlphaHub : Hub 
    { 
     public void Hello(string message) 
     { 
      // We got the string from the Windows Service 
      // using SignalR. Now need to send to the clients 
      Clients.All.addNewMessageToPage(message); 

      // Call Windows Service 
      string message1 = System.Environment.MachineName; 
      Clients.All.Notify(message1); 


     } 
     public void Register(string registrationID,string connectionID) 
     { 
      // We got the string from the Windows Service 
      // using SignalR. Now need to send to the clients 
      System.Web.HttpContext.Current.Application["registrationID"] = registrationID + "|" + connectionID; 
     } 

     public void RecieveDataSet(DataSet ds) 
     { 
      Clients.All.addNewMessageToPage("Data Set recieved"); 
     } 

Здесь Windows Service Code, который генерирует исключение на линии:

await alphaProxy.Invoke("RecieveDataSet", employees); 

Код является:

protected override async void OnStart(string[] args) 
     { 
      eventLog1.WriteEntry("In OnStart"); 
      try 
      { 
       var hubConnection = new HubConnection("http://www.someurl.com/signalr", useDefaultUrl: false); 
       IHubProxy alphaProxy = hubConnection.CreateHubProxy("AlphaHub"); 

       await hubConnection.Start(); 
       string cid = hubConnection.ConnectionId.ToString(); 
       eventLog1.WriteEntry("ConnectionID: " + cid); 
       // Invoke method on hub 

       await alphaProxy.Invoke("Hello", "Message from Service - ConnectionID: " + cid + " - " + System.Environment.MachineName.ToString() + " " + DateTime.Now.ToString()); 
       await 
        alphaProxy.Invoke("Register", "81577f58-0e05-43f4-b322-fbf0d9d1e79e", 
         hubConnection.ConnectionId.ToString()); 


       alphaProxy.On("addNewMessageToPage",() => eventLog1.WriteEntry("Notified!")); 

       DataSet employees = new DataSet(); 
       string connString = "..."; 
       SqlConnection conn = new SqlConnection(connString); 
       string queryString = "SELECT * FROM [HumanResources].[Employee]"; 
       SqlDataAdapter adapter = new SqlDataAdapter(queryString, conn); 
       adapter.Fill(employees, "HumanResources.Employee"); 

       await alphaProxy.Invoke("RecieveDataSet", employees); 
      } 
      catch (Exception ex) 
      { 
       eventLog1.WriteEntry(ex.Message); 
      } 
     } 

Возможно ли передать DataSet? Если нет, мне нужно сериализовать/десериализовать? Если да, можете ли вы показать код для этого?

+0

Вы можете передать объект JSON к вашему JavaScript да. – Gjohn

+0

Здесь я не имею дело с JavaScript. Я пытаюсь вызвать RecieveDataSet в классе Hub на сервере. – user2471435

+0

Пока вы можете создавать JSON, вы можете отправить его, я верю. –

ответ

3

Я рекомендую вам преобразовать ваш набор данных в объект передачи данных и передать это. С SignalR вы можете передавать каждый объект, поскольку он гидратирован, что позволяет вам уведомлять наблюдателей не только при получении, но также и при добавлении любого нового элемента. Я не тестировал этот код, поэтому я, возможно, пропустил что-то, но он должен дать вам эту идею.

adapter.Fill(employees, "HumanResources.Employee"); 
foreach (var dr in employees) 
{ 
    var empDto = new EmployeeDto 
    { 
     FirstName = dr.Fields("FirstName"), 
     LastName = dr.Fields("LastName"), 
     // Additional fields go here... 
    }; 
    alphaProxy.Clients.ReceiveDataSet(empDto); // Serializes the dto as json by default. 
} 

Конечно, если вы хотите, чтобы отправить полный список в ответ вы должны быть в состоянии изменить это немного:

adapter.Fill(employees, "HumanResources.Employee"); 
var items = new List<EmployeeDto>(); 
foreach (var dr in employees) 
{ 
    var empDto = new EmployeeDto 
    { 
     FirstName = dr.Fields("FirstName"), 
     LastName = dr.Fields("LastName"), 
     // Additional fields go here... 
    }; 
    items.Add(empDto); 
} 
alphaProxy.Clients.ReceiveDataSet(items); // Serializes the dto as json array by default. 
0

http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-net-client#clientmethodswithoutparms

Смотрите руководство прохождения методов и без Params.

+0

Прошу прощения. Я не уверен, как это помогает. Он показывает методы сервера, вызывающие методы клиента с/без paarameters. У меня есть клиент, вызывающий метод Server, но я думаю, что передаю параметр, как они показывают ожидание alphaProxy.Invoke («RecieveDataSet», сотрудники); Вы уверены, что можете передавать DataSets? – user2471435

+1

Похоже, что параметр DataSet слишком велик для передачи, поэтому «Недопустимый URI: строка Uri слишком длинная». – user2471435

3

Вы хотите, чтобы ваши сообщения были довольно легкими с SignalR по многим причинам (особенно с масштабированием через объединительные платы), поэтому я НЕ передал бы что-то большое, как DataSet, через сообщение SignalR лично. То, что я обычно предлагаю для больших полезных нагрузок, заключается в том, что вы отправляете конкретное сообщение, которое сообщает браузеру, что оно должно обновлять данные, которые он затем выполняет, загружая с помощью традиционного GET какой-либо службы на основе REST. Таким образом, вы получаете уведомления об обновлениях в режиме реального времени, но вы используете традиционный HTTP GET для передачи фактической полезной нагрузки.

+0

Удовлетворение зависит от того, как упакован набор данных.Если я буду помнить, что JSON-сериализация производит только данные для DataSet, и это не более подробный, чем набор объектов. Не уверен, что это поддерживается SignalR tho. JSON.NET (только в одном случае). –

+0

Да, но я думаю, что это сводится к тому, что, независимо от «формы», общий размер полезной нагрузки. Если есть одна строка/сущность с несколькими столбцами/свойствами, нормально ... «whatevs». Если это будет 10+ строк/сущностей, вероятность того, что он не должен быть доставлен через SignalR msg, и вместо этого сообщение SignalR должно указывать на некоторый URL REST, чтобы сказать «эй, это изменилось, идите проверить себя». Правильный инструмент для работы. –

Смежные вопросы