我在SignalR写一个游戏.这个想法是你用你的笔记本电脑连接,它将用作"显示器",然后你连接智能手机,它将被用作"操纵杆".整个设置非常有效.
现在一切正常,我决定重构代码.我意识到操纵杆和显示器之间的关系是一种方式(显示器永远不需要将信息发送回操纵杆).因此我决定在操纵杆上不需要任何signalR可调用的客户端功能(例如,gameHub.client.joyStickMethod()在操纵杆js中没有用.
就在那时我发现了一些奇怪的东西
事实证明,public override Task OnConnected()除非我定义一个,否则不会调用我覆盖以处理不同类型的客户端(显示和操纵杆)的hub方法myHub.client.clientSideMethod().这是我正在处理的例子:
var gameHub = $.connection.gameHub;
gameHub.client.connection();
$("#joystick").joystick({
hub: gameHub
});
gameHub.client.activateJoystick = function () { };
$.connection.hub.qs = "type=joystick&gameId=" + "@Model.Id";
$.connection.hub.start(); //this will invoke on connected
Run Code Online (Sandbox Code Playgroud)
你看到那个空的客户端方法?这就是为什么OnConnected在服务器端调用的原因.如果我删除该行代码,则不会调用它.
var gameHub = $.connection.gameHub;
gameHub.client.connection();
$("#joystick").joystick({
hub: gameHub
});
//gameHub.client.activateJoystick = function () { };
$.connection.hub.qs = "type=joystick&gameId=" + "@Model.Id";
$.connection.hub.start(); //this will invoke on connected
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为Hub上没有客户端方法.我可以RegistrateJoystick在Hub上添加一个方法并调用它,但我认为这种行为是出乎意料的.我的问题是:
有没有办法手动"连接"到集线器,以便OnConnect调用该方法?
您能否在服务器端识别出哪种传输方法用于给定的SignalR连接?(WebSockets,SSE,长轮询等?)
我在AspNet MVC 4应用程序中使用SignalR 1.1.2版本和Windsor Castle.我的问题是,自从我转移到较新的SignalR版本后,此错误消息显示出来.
"The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly."
Run Code Online (Sandbox Code Playgroud)
在线
RouteTable.Routes.MapHubs();
Run Code Online (Sandbox Code Playgroud)
这是RegisterHubs类
public static class RegisterHubs
{
public static void Start()
{
var signalrDependencyContainer = new WindsorContainer().Install(new HubsInstaller());
var signalrDependency = new SignalrDependencyResolver(signalrDependencyContainer.Kernel);
GlobalHost.DependencyResolver = signalrDependency;
RouteTable.Routes.MapHubs();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了一些我在互联网上找到的东西,比如:
lodctr /R
cd C:\Windows\Inf\.NETFramework
lodctr corperfmonsymbols.ini
Run Code Online (Sandbox Code Playgroud)
但我仍然收到相同的错误消息.有任何想法吗?
我正在使用dotnet framework 4.5.
这是堆栈跟踪
at System.Diagnostics.PerformanceCounter.InitializeImpl()
Run Code Online (Sandbox Code Playgroud)
谢谢!
更新
我正在添加Drew请求的屏幕截图.



我正在使用SignalR 2,我无法弄清楚如何使用我的Hub方法,例如在控制器动作中.
我知道我可以做到以下几点:
var hub = GlobalHost.ConnectionManager.GetHubContext<T>();
hub.Clients.All.clientSideMethod(param);
Run Code Online (Sandbox Code Playgroud)
但是直接在客户端执行该方法.
如果我的服务器端ClientSideMethod(param)方法中有业务逻辑,我想从我的控制器调用,就像从客户端调用它一样?
目前我public static void ClientSideMethod(param)在我的集线器中使用,在那个方法中我使用了IHubContext来自ConnectionManager.
这样做有没有更好的方法?
以下是行不通的(在SignalR 2中?):
var hubManager = new DefaultHubManager(GlobalHost.DependencyResolver);
instance = hubManager.ResolveHub(typeof(T).Name) as T;
instance.ClientSideMethod(param);
Run Code Online (Sandbox Code Playgroud)
在访问客户端时,我得到"不通过Hub管道创建的集线器不受支持"异常.
我需要SignalR开发人员的一些指导,这是调整HUB方法参数序列化的最佳方法.
我开始将我的项目从WCF轮询双工(Silverlight 5 - ASP.NET 4.5)迁移到SignalR(1.1.2).消息(数据契约)是基于接口的多态的.(与IMessage,MessageA:IMessage等一样 - 实际上存在由类实现的接口的层次结构,但它对于该问题并没有多大意义).(我知道多态对象不适合客户端,但客户端会将其作为JSON处理,并且只有在服务器端或客户端上才能映射到对象(如果它是.NET/Silverlight)
在集线器上我定义了这样的方法:
public void SendMessage(IMessage data) { .. }
Run Code Online (Sandbox Code Playgroud)
我创建了自定义JsonConverters并验证了可以使用Json.NET对消息进行序列化/反序列化.然后我用适当的设置替换了DependencyResolver中的JsonNetSerializer.同样在Silverlight客户端.到现在为止还挺好.
但是当我将消息从客户端发送到服务器(消息被正确地序列化为JSON - 在Fiddler中验证)时,服务器返回错误,该参数无法反序列化.在调试器的帮助下,我在SignalR中发现了一个错误(负责反序列化的JRawValue类在内部创建了自己的JsonSerializer实例,忽略了提供的一个).通过替换看起来很容易解决
var settings = new JsonSerializerSettings
{
MaxDepth = 20
};
var serializer = JsonSerializer.Create(settings);
return serializer.Deserialize(jsonReader, type);
Run Code Online (Sandbox Code Playgroud)
同
var serializer = GlobalHost.DependencyResolver.Resolve<IJsonSerializer>();
return serializer.Parse(jsonReader, type);
Run Code Online (Sandbox Code Playgroud)
但我也发现在未来版本的SignalR中将删除IJsonSerializer接口.基本上,我需要从HUB方法获取原始JSON(或字节流),以便我可以自己反序列化它,或者通过指定转换器等来调整序列化器的可能性.
现在我最终用JObject参数类型定义了方法:
public void SendMessage(JObject data)
Run Code Online (Sandbox Code Playgroud)
然后使用手动反序列化数据
JObject.ToObject<IMessage>(JsonSerializer)
Run Code Online (Sandbox Code Playgroud)
方法.但我更喜欢自定义序列化程序并在hub方法上使用类型/接口.关于下一个SignalR设计的"正确方法"是什么?
我还发现有可能从我的代码发送回客户端原始JSON,即使SignalR再次序列化对象.我怎么能实现这个目标?
请注意,我在这里明确地引用了SignalR 2.0 ...我已经看到了一些(讨厌的)方法用于SignalR 1.1/1.2 ......但是还没有用于2.0.
有没有人在更改SignalR 2.0默认的json序列化程序以启用派生类型的发送方面有任何成功?根据我读到的有关SignalR 2.0的内容,这应该是可能的,但是,我没有运气,也没有在任何地方找到完整的例子.
这是我开始的方式...任何帮助将不胜感激.
我的Startup.cs
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// this should allow the json serializer to maintain the object structures
var serializer = new JsonSerializer()
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Objects,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
};
// register it so that signalr can pick it up
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);
app.MapSignalR();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Hub上的方法
public void AddStock(Stock stock)
{
string stockType = stock.GetType().ToString(); …Run Code Online (Sandbox Code Playgroud) 我在VS2012中创建了一个Windows托管的SignalR集线器:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
public static class SignalR
{
public static void Start()
{
const string url = "http://*:8080";
WebApp.Start<Startup>(url);
}
}
public class Broadcaster : Hub
{
public void SendDownloadResult(bool result, string device, string description, string connectionId, string task)
{
var context = GlobalHost.ConnectionManager.GetHubContext<Broadcaster>();
context.Clients.Client(connectionId).sendDownloadResult(result, device, description, task);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经在3台不同的PC上部署了这个Windows服务,它可以在两台PC上正常工作,但另一方面,当我尝试浏览时,我得到HTTP 503服务不可用 http://localhost:8080/signalr/hubs
在所有3台PC上执行代码时不会抛出异常.
我已经在添加/删除Windows功能中检查了IIS的功能,它们都是一样的.
我错过了什么?
我一直在尝试按照CodeProject上的"Asp.Net SignalR聊天室"教程(http://www.codeproject.com/Articles/562023/Asp-Net-SignalR-Chat-Room)实现聊天室.但是,我收到错误"Hubs.ChatHubs.OnDisconnected():找不到合适的方法来覆盖"
ChatHub类:
public class ChatHub : Hub
{
#region Data Members
static List<UserDetail> ConnectedUsers = new List<UserDetail>();
static List<MessageDetail> CurrentMessage = new List<MessageDetail>();
#endregion
#region Methods
public void Connect(string userName)
{
var id = Context.ConnectionId;
if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
{
ConnectedUsers.Add(new UserDetail { ConnectionId = id, UserName = userName });
// send to caller
Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);
// send to all except caller client
Clients.AllExcept(id).onNewUserConnected(id, userName);
}
}
public void SendMessageToAll(string userName, …Run Code Online (Sandbox Code Playgroud) (这是一个Q/A风格的问题,旨在成为那些提出类似问题的人的首选资源.很多人似乎偶然发现了这样做的最佳方式,因为他们不知道所有的选择许多答案都是ASP.NET特有的,但AJAX和其他技术确实在其他框架中具有等价物,例如socket.io和SignalR.)
我有一个我在ASP.NET中实现的数据表.我想实时或接近实时地显示页面上此基础数据的更改.我该怎么办呢?
我的型号:
public class BoardGame
{
public int Id { get; set;}
public string Name { get; set;}
public string Description { get; set;}
public int Quantity { get; set;}
public double Price { get; set;}
public BoardGame() { }
public BoardGame(int id, string name, string description, int quantity, double price)
{
Id=id;
Name=name;
Description=description;
Quantity=quantity;
Price=price;
}
}
Run Code Online (Sandbox Code Playgroud)
代替这个例子的实际数据库,我只是将数据存储在Application变量中.我将在我Application_Start的Global.asax.cs函数中播种它.
var SeedData = new List<BoardGame>(){
new BoardGame(1, "Monopoly","Make your opponents go bankrupt!", 76, 15),
new …Run Code Online (Sandbox Code Playgroud) 我在ASP .NET Core Web API应用程序中使用JWT身份验证令牌.令牌由API本身生成,而不是由第三方生成.我成功地将SignalR添加到堆栈中,但现在我需要对尝试执行服务器(Hub)方法的用户进行身份验证.有人建议在JavaScript中的"qs"属性中传递令牌.这对我来说不起作用,因为我们的代币非常大(它们包含很多索赔).我尝试编写一个自定义中间件,用于从有效负载中读取令牌并自动验证用户.问题是,使用WebSockets时,不会执行中间件.任何想法都会有所帮助
signalr ×10
c# ×6
signalr-hub ×5
asp.net ×3
.net ×1
ajax ×1
asp.net-core ×1
asp.net-mvc ×1
javascript ×1
jwt ×1