2017-06-02 10 views
1

従ってくださいコード:SqlDependency

_layout:

$(function() { 
    var connection = $.connection.notificationHub; 

    //signalr method for push server message to client 
    connection.client.addNotification = function (who) { 
     //send notification here 
     console.info("Send Notification") 
    }; 

    // Start hub 
    $.connection.hub.start().done(function() { 
     console.log("SignalR Started") 
    }); 
}); 

Global.asax.cs:

public class Global : HttpApplication 
{ 
    string con = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString; 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 

     //here in Application Start we will start Sql Dependency 
     SqlDependency.Start(con); 
    } 

    protected void Session_Start(object sender, EventArgs e) 
    { 
     NotificationComponent NC = new NotificationComponent(); 
     var currentTime = DateTime.Now; 
     HttpContext.Current.Session["LastUpdated"] = currentTime; 
     NC.RegisterNotification(currentTime); 
    } 

    protected void Application_End() 
    { 
     //here we will stop Sql Dependency 
     SqlDependency.Stop(con); 
    } 
} 

コントローラー:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult MyAction(string parameter) 
{ 
    //Database Notification (Table - Contacts) -Add or Update 
    ctx.SaveChanges(); 
} 

NotificationHub:ハブ

private readonly static ConnectionMapping<string> _connections = new ConnectionMapping<string>(); 

public static void SendNotification(string who) 
{ 
    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>(); 
    foreach (var connectionId in _connections.GetConnections(who)) 
    { 
     var result = context.Clients.Client(connectionId); 
     if (result != null) 
     { 
      result.addNotification(who); 
     } 
    } 
} 

Components.cs:

public void RegisterNotification(DateTime currentTime) 
{ 
    string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString; 
    string sqlCommand = @"SELECT [ContactID],[ContactName],[ContactNo] from [dbo].[Contacts] where [AddedOn] > @AddedOn"; 
    //you can notice here I have added table name like this [dbo].[Contacts] with [dbo], its mendatory when you use Sql Dependency 
    using (SqlConnection con = new SqlConnection(conStr)) 
    { 
     SqlCommand cmd = new SqlCommand(sqlCommand, con); 
     cmd.Parameters.AddWithValue("@AddedOn", currentTime); 
     if (con.State != System.Data.ConnectionState.Open) 
     { 
      con.Open(); 
     } 
     cmd.Notification = null; 
     SqlDependency sqlDep = new SqlDependency(cmd); 
     sqlDep.OnChange += sqlDep_OnChange; 
     //we must have to execute the command here 
     using (SqlDataReader reader = cmd.ExecuteReader()) 
     { 
      // nothing need to add here now 
     } 
    } 
} 

//After code `ctx.SaveChanges()`, call the code below (50 times): 
void SqlDep_OnChange(object sender, SqlNotificationEventArgs e) //<-- Here Problem 
{ 

    //from here we will send notification message to client 
    NotificationHub.SendNotification("User1586"); 
    //... 

    //re-register notification 
    RegisterNotification(DateTime.Now); 

    //HERE -After this line "RegisterNotification(DateTime.Now);", it returns again to the line: "void SqlDep_OnChange(object sender, SqlNotificationEventArgs e)" 
} 

ユーザー "User1586は、" 複数の通知を受信して​​います。 行"void SqlDep_OnChange(object sender, SqlNotificationEventArgs e)"が何度か繰り返されます。あなたが1000人のオンラインユーザーがいる場合は1000倍は、この行に、

void SqlDep_OnChange(object sender, SqlNotificationEventArgs e) 

ん:つまり

void SqlDep_OnChange(object sender, SqlNotificationEventArgs e). 

、ユーザー「User1586あなたは50人のオンラインユーザーがいる場合、この行に50回行う いくつかの通知を受け取ります。

私はここで例に従っ:http://www.dotnetawesome.com/2016/05/push-notification-system-with-signalr.html

アイデアは、データベースの更新後に、特定のユーザに通知を送信することです。

答えて

1

まず、SQLの依存関係が変更されたどのようなデータを認識しません。したがって、イベントハンドラ内でクエリを実行する必要があります。ユーザーIDに対応するデータを、1人のユーザー専用に送信する場合は、このようにすることをお勧めします。私は理解していない

イベントハンドラ

private void SqlDependency_OnChange(object sender, SqlNotificationEventArgs e) 
{ 
    if (e.Info == SqlNotificationInfo.Insert) 
    { 
     RecordInfo info = GetLastInsertedRecord(); //Just a custom entity 
      if(info.UserId > 0) 
      NotificationHub.SendNotification(info.UserId); 
    } 
    RegisterNotification(DateTime.Now); 
} 

ハブ

public static List<UserConnection> ListUser { get; set; } 
public static void SendNotification(string who) 
{ 
    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); 
    // Get specific user from connected ones. 
    string Id = ListUser.Find(x => x.UserId == who).ConnectionId; 
    context.Clients.Client(Id).addNotification(who); // or another data 
} 
//Add every connected users to the list 
public override Task OnConnected() 
    { 
     ListUser = new List<UserConnection>(); 
     var us = new UserConnection(); 
     us.UserId = Context.QueryString["UserId"]; 
     us.ConnectionId = Context.ConnectionId; 
     ListUser.Add(us); 

     return base.OnConnected(); 
    } 

UPDATEクライアント

$(function() { 
    var connection = $.connection.notificationHub; 
    //Pass the userId here as querystring 
    $.connection.hub.qs = "UserId=" + $("#labelHoldsUserId").val(); 
    //signalr method for push server message to client 
    connection.client.addNotification = function (who) { 
     //send notification here 
     console.log(who + " sends message"); 
    }; 

    // Start hub 
    $.connection.hub.start().done(function() { 
     console.log("SignalR Started") 
    }); 
}) 
+0

ibubi、お願い、私は興味があります。 – UserMat2017

+0

@ UserMat2017投稿を更新しました – ibubi

+0

ありがとう – UserMat2017

0

OnChangeハンドラとSqlDependencyインスタンスは、どちらも1つのイベントに対してのみ有効です。イベントが発生し、ハンドラの登録を解除すると、ハンドラを新しいSqlDependencyオブジェクトに登録する必要があります。

詳細はこちらのリンクをご覧ください。すべてのhttp://msdn.microsoft.com/en-us/library/a52dhwx7(v=vs.80).aspx

+1

は、あなたは私の例を与えることができますか? – UserMat2017

関連する問題