Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在我的非常简单的方法中,为什么在运行时无法访问集线器上下文连接ID?_C#_Asp.net_Signalr_Signalr Hub - Fatal编程技术网

C# 在我的非常简单的方法中,为什么在运行时无法访问集线器上下文连接ID?

C# 在我的非常简单的方法中,为什么在运行时无法访问集线器上下文连接ID?,c#,asp.net,signalr,signalr-hub,C#,Asp.net,Signalr,Signalr Hub,首先,我要说的是,除了一件事之外,所有这一切目前都非常有效——进度条的通知更新将发送给所有客户端(正如您所期望的那样,我使用的代码示例将发送给…clients.all) 我所要做的就是将通知发送回发起当前集线器调用的客户端。就这样,没别的了。在这个网站上没有“登录”的概念,所以没有用户身份信息 我的方法是: public void NotifyUpdates(decimal val) { var hubContext = GlobalHost.ConnectionManager.GetH

首先,我要说的是,除了一件事之外,所有这一切目前都非常有效——进度条的通知更新将发送给所有客户端(正如您所期望的那样,我使用的代码示例将发送给
…clients.all

我所要做的就是将通知发送回发起当前集线器调用的客户端。就这样,没别的了。在这个网站上没有“登录”的概念,所以没有用户身份信息

我的方法是:

public void NotifyUpdates(decimal val)
{
    var hubContext = GlobalHost.ConnectionManager.GetHubContext<EventsForceHub>();

    if (hubContext != null)
    {
        //"updateProgress" is javascript event trigger name
        await hubContext.Clients.All.updateProgress(val); 
    }
}
…然后我就得到一个

“不包含“连接”的定义”

错误,我就是不明白

我也尝试过从该方法访问
Context.ConnectionId
,但是
Context
在那一点上是
null
,所以我有点困惑。使用
NotifyUpdates
将信息发送回客户端的服务器方法是通过普通的asp.net按钮调用的,而不是通过AJAX调用的

结构澄清

我认为这里有一定程度的混乱。这是一个非常简单的网页,上面有一个asp.net按钮控件。该按钮的eventhandler调用异步方法,通过服务调用/存储库从服务器返回数据


在异步方法内部,它必须处理每个返回的数据行,并进行三到四次远程web api调用。在每个循环中,我用一个完整的百分比调用上面显示的
NotifyUpdates
signar方法,这样就可以通过指定方法名的事件处理程序将其更新回客户端(
updateProgress
,如上所示)。可能有几十条数据线,每条数据线都需要对远程服务器调用几个Web API来添加数据。每次迭代可能需要几秒钟的时间,因此我会通过
updateProgress
方法调用将“更新进度”发送回客户端。

如果您想将通知发送回客户端 您不应该打电话给

hubContext.Clients.All.updateProgress(val);
相反,尝试

访问当前用户的ConnectionId并使用Clients.Client

hubContext.Clients.Client(Context.ConnectionId);

新答案

根据您的评论,我做了以下小测试:

它将允许客户端使用
clientName
连接到集线器,并且每个客户端都在侦听发送给他们的更新。我们将为他们定义一个组,以便他们能够从服务器端通知他们

我制作了一个虚拟的进程模拟器类来向用户抛出一些更新值

守则:

枢纽等级:

public class EventsForceHub : Hub {
    public static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<EventsForceHub>();

    // allow users to join to hub and get s dedicated group/channel for them, so we can update them
    public async Task JoinGroup(string clientName) {
        string clientID = Context.ConnectionId;
        ClientInfo.clients.Add(clientID, new MyAppClient(clientID, clientName));
        await Groups.Add(clientID, clientName);

        // this is just mockup to simulate progress events (this uis not needed in real application)
        MockupProgressGenerator.DoJob(clientName, 0);
    }

    public static void NotifyUpdates(decimal val, string clientName) {
        // update the given client on his group/channel
        hubContext.Clients.Group(clientName).updateProgress(val);
    }
}
公共类事件ForceHub:Hub{
public static IHubContext hubContext=GlobalHost.ConnectionManager.GetHubContext();
//允许用户加入hub并为他们获取s专用组/频道,以便我们可以更新他们
公共异步任务JoinGroup(字符串clientName){
字符串clientID=Context.ConnectionId;
Add(clientID,newmyappclient(clientID,clientName));
等待组。添加(clientID,clientName);
//这只是模拟进度事件的模型(实际应用程序中不需要此UI)
MockupProgressGenerator.DoJob(clientName,0);
}
公共静态更新(十进制值、字符串clientName){
//在其组/频道上更新给定客户端
hubContext.Clients.Group(clientName).updateProgress(val);
}
}
一些小助手类:

// client "storage"
public static class ClientInfo  {
    public static Dictionary<string, MyAppClient> clients = new Dictionary<string, MyAppClient>();
    // .. further data and methods
}

// client type
public class MyAppClient {
    public string Id { get; set; }
    public string Name { get; set; }
    // .. further prooerties and methods

    public MyAppClient(string id, string name) {
        Id = id;
        Name = name;
    }
}

// this a completely made up and dumb class to simulate slow process and give some simple progress events
public static class MockupProgressGenerator {
    public static void DoJob(string clientName, int status) {
        if (status < 100) {
            Task.Delay(1000).ContinueWith(a =>
            {
                EventsForceHub.NotifyUpdates(status += 20, clientName);
                DoJob(clientName, status);
            });
        }
    }
}
//客户端“存储”
公共静态类ClientInfo{
公共静态字典客户端=新字典();
//…进一步的数据和方法
}
//客户端类型
公共类MyAppClient{
公共字符串Id{get;set;}
公共字符串名称{get;set;}
//…进一步的项目和方法
公共MyAppClient(字符串id、字符串名称){
Id=Id;
名称=名称;
}
}
//这是一个完全虚构的哑巴类,用来模拟缓慢的进程并给出一些简单的进度事件
公共静态类mockuppressGenerator{
公共静态void DoJob(字符串clientName,int status){
如果(状态<100){
任务。延迟(1000)。继续(a=>
{
EventsForceHub.NotifyUpdates(状态+=20,客户端名称);
DoJob(客户端名称、状态);
});
}
}
}
让我们看看JS中的两个简单客户端:

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

        $.connection.hub.start().done(function () {
            $('body').append("Joining with Name: Jerry");
            eventsForceHub.server.joinGroup("Jerry");
        });

        eventsForceHub.client.updateProgress = function (val) {
            // message received
            $('body').append('<br>').append("New Progress message: " + val);
        };
    });
$(函数(){
var eventsForceHub=$.connection.eventsForceHub;
$.connection.hub.start().done(函数(){
$('body').append(“与姓名连用:Jerry”);
eventsForceHub.server.joinGroup(“Jerry”);
});
eventsForceHub.client.updateProgress=函数(val){
//收到的信息
$('body').append('
').append(“新进度消息:“+val”); }; });
为了简单起见,相同的代码和不同的参数,我甚至将其放在两个不同的html页面中,并以稍有不同的时间声明执行

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

        $.connection.hub.start().done(function () {
            $('body').append("Joining with Name: Tom");
            eventsForceHub.server.joinGroup("Tom");
        });

        eventsForceHub.client.updateProgress = function (val) {
            // message received
            $('body').append('<br>').append("New Progress message: " + val);
        };
    });
$(函数(){
var eventsForceHub=$.connection.eventsForceHub;
$.connection.hub.start().done(函数(){
$('body').append(“与Name:Tom合并”);
eventsForceHub.server.joinGroup(“Tom”);
});
eventsForceHub.client.updateProgress=函数(val){
//收到的信息
$('body').append('
').append(“新进度消息:“+val”); }; });
在行动中看到它:


第一个答案

我制作了一个小的web应用程序来验证您的声明。您可以创建以下内容,以便能够将问题与其他可能的问题隔离开来

我创建了一个空的Web应用程序并包含了SignalR

这是hub类:

public class EventsForceHub : Hub {
    public void NotifyUpdates(decimal val) {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<EventsForceHub>();

        if (Context != null) {
            string clientID = Context.ConnectionId;         // <-- on debug: Ok has conn id.
            object caller = Clients.Caller;                 // <-- on debug: Ok, not null
            object caller2 = Clients.Client(clientID);      // <-- on debug: Ok, not null
            Clients.Caller.updateProgress(val);             // Message sent
            Clients.Client(clientID).updateProgress(val);   // Message sent
        }

        if (hubContext != null) {
            //"updateProgress" is javascript event trigger name
            hubContext.Clients.All.updateProgress(val);     // Message sent
        }
    }
}
公共类事件ForceHub:Hub{
公共更新(十进制val){
var hubContext=GlobalHost.ConnectionManager.GetHubContext();
if(上下文!=null){
字符串客户端ID=
public class EventsForceHub : Hub {
    public void NotifyUpdates(decimal val) {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<EventsForceHub>();

        if (Context != null) {
            string clientID = Context.ConnectionId;         // <-- on debug: Ok has conn id.
            object caller = Clients.Caller;                 // <-- on debug: Ok, not null
            object caller2 = Clients.Client(clientID);      // <-- on debug: Ok, not null
            Clients.Caller.updateProgress(val);             // Message sent
            Clients.Client(clientID).updateProgress(val);   // Message sent
        }

        if (hubContext != null) {
            //"updateProgress" is javascript event trigger name
            hubContext.Clients.All.updateProgress(val);     // Message sent
        }
    }
}
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.2.2.min.js"></script>
<script src="signalr/hubs"></script>
<script type="text/javascript">
    $(function () {
        var eventsForceHub = $.connection.eventsForceHub;

        $.connection.hub.start().done(function () {
            // send mock message on start
            console.log("Sending mock message: " + 42);
            eventsForceHub.server.notifyUpdates(42);
        });

        eventsForceHub.client.updateProgress = function (val) {
            // message received
            console.log("New Progress message: " + val);
        };
    });
</script>