使用SignalR通知当前调用 [英] Using SignalR to notify current caller

查看:475
本文介绍了使用SignalR通知当前调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的POST操作常规,我怎么能发送给一些JavaScript的通知在客户端上运行?看来SignalR应该是一个简单的解决方案,但我不知道该怎么做一个回调到SignalR客户端住在JavaScript中的POST操作的客户端页面。

In my POST action routine, how can I send a notification to some JavaScript running in the client? It seems that SignalR should be an easy solution, but I don't know how to do a callback to the SignalR client that lives in JavaScript in the POST action's client page.

具体而言,看来我需要一个连接ID,以便让SignalR去跟一个特定的客户端,但我不知道如何让那些无论是在我的职务行为或在客户端的JavaScript之一。

Specifically, it seems that I need a "connection ID" in order to ask SignalR to talk to a specific client, but I don't know how to get one of those either in my POST action or in the client JavaScript.

在我的MVC应用程序,我POST操作可能需要较长时间才能完成。如果POST操作决定,这将需要很长的时间才能完成,我要通知页面上的一些JavaScript,以便它可以显示的请稍等......的通知给用户。

In my MVC app, my POST action may take a long time to complete. If the POST action decides that it will take a long time to complete, I want to notify some JavaScript on the page so that it can display a "please wait..." notification to the user.

这似乎喜欢的事,SignalR应该很容易对我来说。继<一个href=\"http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc\"相对=nofollow>基础教程,我加了一个集线器,并创造了在我看来,一个JS回调:

This seems like something that SignalR should make really easy for me. Following the basic tutorial, I added a Hub and created a JS callback in my view:

请注意,该中心没有任何方法。我的客户端只需要一个只读的通知。它不需要调用在集线器任何方法来写邮件到外面的世界。

Note that the Hub has no methods. My client only needs a read-only notification. It has no need to call any methods on the Hub to write message to the outside world.

public class MyHub: Hub
{
}

该视图只是有一个提交按钮和一个隐藏的请等待的消息,该SignalR程序可以显示的格式。视图模型,我可以用它来连接ID通过SignalR到POST控制器(假设我能弄清楚如何得到它)的字符串属性。

The view just has a form with a submit button and a hidden "Please wait" message that the SignalR routine can display. The view model has a string property that I can use to pass the SignalR "connection ID" to the POST controller (assuming I can figure out how to get it).

@model SignalRTest.Models.MyViewModel

@using (Html.BeginForm()) {
    @Html.HiddenFor(m => m.SignalrConnectionId)
    <button type="submit" class="btn btn-primary">Go to it!</button>
}

<div id="hidden-msg" hidden="hidden">
    <p>Please wait...</p>
</div>

@section scripts {
    <!-- Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>

    <!-- Reference the autogenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>

    <!-- SignalR script to update the page -->
    <script>
        $(function () {
            // Get a reference to the server "hub" class (camelCase)
            var hub = $.connection.interviewDoneHub;

            // Get our connection ID and store it in a hidden field
            // so that it is sent to the POST action
            // var connectionId = $.connection.hub.id; //This doesn't work!
            // $('#@Html.IdFor(m => m.SignalrConnectionId)').attr(connectionId, '');

            // Create a function that the hub can call
            hub.client.myCallback = function () {
                $('#hidden-msg').show();
            };

            // Start the connection.
            $.connection.hub.start().done(function () {
            });
        });
    </script>
}

同时回到我的岗位控制器操作,我所说的JS回调:

Meanwhile back in my POST controller action, I call the JS callback:

[HttpPost]
public async Task<ActionResult> MyAction(MyViewModel model)
{
    // We've decided that this will take a while.  Tell the client about it...
    var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
    context.Clients.All.myCallback();
    //context.Clients.Client(model.SignalrConnectionId).myCallback();

    await Task.Delay(2000);
    return RedirectToAction("NextPage");
}

现在,我的问题:作为证据的概念测试,我用这个code调用JS回调:

Now, my problem: As a proof-of-concept test, I use this code to call the JS callback:

var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.myCallback();

该工作只是花花公子。但是,很明显,我要打电话与POST操作相关联的特定的客户端。 C#智能感知告诉我,我应该能够调用

which works just dandy. But, obviously, I want to call the specific client associated with the POST action. C# Intellisense tells me that I should be able to call

context.Clients.Client("connectionId").myCallback();

但我无法弄清楚如何获得想要的的ConnectionId字符串。我不认为我将能够获取客户端ID在POST控制器,因为我没有任何形式的在这一点上SignalR连接到客户端。我想我让客户得到它的连接ID,并给它在视图模型中的POST控制器,但我还没有找到魔JS code,它获取的连接ID了SignalR框架。

but I can't figure out how to get the desired "connectionId" string. I don't think I'll be able to get the client ID in the POST controller because I don't have any sort of SignalR connection to the client at that point. I figured I'd let the client get its connection ID and give it to the POST controller in the view model, but I haven't found the magic JS code that fetches the connection ID out of the SignalR framework.

我发现了几个所陈述就事论事,实事求是地SO文章:

I found several SO articles that stated matter-of-factly:

的ConnectionId = $ .connection.hub.id;

connectionId = $.connection.hub.id;

但返回未定义。我发现这个 SignalR JS客户Wiki页面,它说:

but this returns undefined. I found this SignalR JS Client Wiki page, which says:

connection.id结果
    获取或设置客户端ID为当前连接

connection.id
Gets or sets the client id for the current connection

但也返回未定义

这回来到我原来的问题。也许我不理解有关连接ID是什么东西根本...

Which gets back to my original question. Maybe I'm not understanding something fundamental about what a connection ID is...

推荐答案

好吧,我相信我看到的问题是什么。你想开始在JavaScript中的连接

Okay I believe I see what the issue is. You want to start the your connection in javascript

$.connection.hub.start()

你这样做之后,那么你应该能够做到connection.hub.id - 如果连接未启动,然后就没有连接ID可言,这就是为什么你得到,因为它是未定义值直到你开始连接没有被设置。

After you do that, then your should be able to do connection.hub.id - if the connection is not started then there will be no connection id at all, which is why you are getting an "undefined" value because it has not been set until you start the connection.

其实这可能是一个事物的私生子,不知道这是否会工作,但应该只需要最少的更改您的code。每一个客户端连接到集线器时间,您可以将其添加到连接方法

Actually this could be a bastardization of things, not sure if it will work but should require minimal changes to your code. Each time a client connects to your hub you can add this to the connect method

Groups.Add(Context.ConnectionId, Context.ConnectionId); 
// name it the same as your connection id since that is the identified you are using

然后在你的控制器,你可以添加以下你的行动呼吁

Then in your controller you can add the following in your action call

var context = GlobalHost.ConnectionManager.GetHubContext<InterviewDoneHub>();
context.Clients.Groups(connectionId).myCallback();


如果以上不工作,那么你将不得不连接到使用的。NET客户。就像你可以使用C#连接到集线器javascript和调用一个方法那么就会通知你想通知的客户端连接。我该使用的WebAPI过去,但我相当肯定,它可以在Asp.Net MVC做,以及做了。


If the above does not work then you are going to have to connect to the hub using .NET Client. Just like you connected from javascript you can connect to the hub using C# and call a method that will then notify the client you want notified. I did this using WebAPI in the past but I am fairly certain that it can be done in Asp.Net MVC as well.

这篇关于使用SignalR通知当前调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆