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>