我们有一个名为StatusUpdateHub的SignalR集线器.此集线器由名为HubClient的.NET客户端更新.对于不同的交易,该客户端(在生产中)被多个用户每秒调用大约1000次.这是客户端代码:
public static class HubClient
{
private static readonly string statusUpdateUrl = ConfigurationManager.AppSettings["StatusUpdateUrl"];
private static readonly HubConnection connection = new HubConnection(statusUpdateUrl);
private static readonly IHubProxy hub = connection.CreateProxy("StatusUpdateHub");
internal static void UpdateBrowser(long transactionId)
{
connection.Start().ContinueWith(task => hub.Invoke("UpdateTransactionStatus", transactionId)).ContinueWith(task =>
{
if (task.IsFaulted && task.Exception != null)
{
// log error
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
当使用100个并发用户调用此代码时它工作正常但是当我们将并发用户数增加到250时,我们看到以下错误:
UpdateBrowser中出现意外错误:System.InvalidOperationException:尚未建立连接.位于SignalR.Client.Hubs的SignalR.Client.Hubs.HubProxy.Invoke [T](String方法,Object [] args)上的SignalR.Client.Connection.SignalR.Client.IConnection.Send [T](字符串数据).位于C:\ Build\Work\Application\Services\HubClient.cs 中的Application.Services.HubClient.<> c_ DisplayClass2.b _0(任务task1)中的HubProxy.Invoke(String方法,Object [] args):
系统中的第20行
System.Threading.Tasks.Task.Execute()中的.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj )
让我们知道如何使代码更具可扩展性?
我在我的应用程序中使用SignalR.我有一个应用程序,在很大程度上取决于OnDisconnected()被正确调用.在以下情况下正确调用它:
public Task OnDisconnected()
{
try
{
DeleteUser(Context.ConnectionId);
return null;
}
catch (Exception ex)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果网络连接突然下降,则不会调用它.例如,如果我拔掉客户端计算机上的网络电缆,或者禁用客户端的无线网络,或者拔掉路由器OnDisconnected(),即使在等待几分钟后也不会被呼叫.
我尝试使用两个Receive方法创建一个基本集线器,一个接受一个字符串,另一个接受一个int.这会导致错误,指出无法解析该方法.注释掉其中一个方法可以消除错误并且一切正常.
我的集线器中是否可能存在方法的重载?是否可以完成重载之类的事情?
进行下载或上传文件(WebClient.DownloadFileAsync | UploadFileAsync或HttpWebRequest)并同时调用SignalR-hub方法时出现问题:
SignalR调用已停止,直到文件加载完成.看起来就是这样:所有信号员都会进行排队.所有排队的调用都会进一步执行(文件加载后).
我的代码片段:
hubProxy.Invoke("TraceDocumentUploadingRequest", callerId, fileName, "File loading started ", 0);
DownloadFileByKey(fileKey, (progressPercentage, bytesSent) => { hubProxy.Invoke("TraceDocumentUploadingRequest", callerId, fileName, "File loading in progress", progressPercentage); });
hubProxy.Invoke("TraceDocumentUploadingRequest", callerId, fileName, "File loading finished", 100);
Run Code Online (Sandbox Code Playgroud)
文件下载完成后,将在集线器上执行第二个"TraceDocumentUploadingRequest"集线器方法调用(在文件加载处理程序中).
文件加载处理程序在当前线程或另一个线程中执行(与DownloadFileByKey方法实现相关) - 结果是相同的.
我怎样才能避免这种行为并在正确的时间强制使用hub-method调用?
我想知道是否可以将SignalR 放在Hub与Asp.Net项目不同的项目中?如果是的话.我怎样才能访问Hub课程?
提前致谢.
我想知道是否可以将结果转换
var hub = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
为我实际的ChatHub类.因为GlobalHost.ConnectionManager.GetHubContext<ChatHub>() as ChatHub失败了
在我的ChatHub类中,我有一个方法UpdateTime():
public void SendTimeUpdate(DateTime time, string auth)
{
Clients.All.UpdateTime(time, auth);
}
Run Code Online (Sandbox Code Playgroud)
我想从我的其他班级称呼它.由于我无法转换为ChatHub并调用SendUpdate,我必须去:
GlobalHost.ConnectionManager.GetHubContext<ChatHub>().Clients.All.UpdateTime(time, auth);
Run Code Online (Sandbox Code Playgroud)
但是,如果我走这条路,方法SendTimeUpdate不会添加到代理脚本/ signalr/hubs中
有这个问题的解决方案吗?我想获取类型化的Hub实例,而不是直接在IHubContext的Clients属性上调用stuff.
无论如何为hub功能定义和添加方法过滤器(如mvc中的ActionFilters)我的意思是这样的:
public class MyHub : Hub
{
[Log]
public string RegisterUser(UserModel model){
...
}
}
Run Code Online (Sandbox Code Playgroud)
我可以在LogAttribute实现中做一些控制.
嗨,我在思考是否可以使用SignalR松开消息.假设客户端断开但最终在很短的时间内重新连接,例如3秒.客户端是否会收到断开连接时发送给他的所有消息?
例如,让我们考虑LongPolling传输.据我所知,长轮询是一个简单的http请求,由客户端提前发出,以便等待服务器事件.
一旦服务器事件发生,数据就会在http请求上发布,从而导致在发出的http请求上关闭连接.之后,客户端发出新的http请求,再次重复整个循环.
假设两个事件发生在服务器上,第一A则B(几乎瞬时).客户端获取A与关闭http连接结果的消息.现在要获取消息B客户端必须发出第二个http请求.
如果B事件发生在客户端与服务器断开连接并尝试重新连接时.
客户端是否会B自动获取消息,或者我必须发明某种确保消息完整性的机制?
这个问题不仅适用于长轮询,也适用于客户重新连接的一般情况.
PS我在服务器端使用SignalR Hubs.
编辑:
我发现消息的顺序无法保证,我无法使SignalR松散消息
我有一个signalR服务器(控制台应用程序)和一个客户端应用程序(Asp.net MVC5)
如何在OAuth成员资格中向特定用户发送消息.
实际上我无法从中心请求上下文中解析发件人用户.
Context.User.Identity.Name
Run Code Online (Sandbox Code Playgroud)
我的中心
public class UserHub : Hub
{
#region Hub Methods
public void LoggedIn(string userName, string uniqueId, string ip)
{
Clients.All.userLoggedIn(userName, uniqueId, ip);
}
public void LoggedOut(string userName, string uniqueId, string ip)
{
var t = ClaimsPrincipal.Current.Identity.Name;
Clients.All.userLoggedOut(userName, uniqueId, ip);
}
public void SendMessage(string sendFromId, string userId, string sendFromName, string userName, string message)
{
Clients.User(userName).sendMessage(sendFromId, userId, sendFromName, userName, message);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
启动集线器类(Program.cs)
class Program
{
static void Main(string[] args)
{
string url = string.Format("http://localhost:{0}", ConfigurationManager.AppSettings["SignalRServerPort"]); …Run Code Online (Sandbox Code Playgroud) 我正在寻找关于如何在自托管(非IIS)环境中运行的后端服务上实现SignalR的授权安全性的一些指导,该环境是从Web应用程序调用的.后端应用程序基本上是一个监视器,可以将SignalR事件激发回基于HTML的客户端.这一切都很好(实际上非常好).
但是,我们需要从Web站点限制对经过身份验证的用户的服务器访问.所以基本上如果用户在网站上进行了身份验证,我们需要在后端应用程序中以某种方式获取凭据(用户名就足够了)和验证状态,以决定是否允许连接以避免未经授权的访问.
任何人都可以指出如何完成这种授权转发的一些策略或模式?