我正在使用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再次序列化对象.我怎么能实现这个目标?
我一直在尝试按照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) 我刚刚开始探索signalR,我希望能够从服务器向所有客户端发送消息.
这是我的中心
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SignalR;
using SignalR.Hubs;
using SignalR.Hosting.Common;
using SignalR.Hosting.AspNet;
using System.Threading.Tasks;
namespace MvcApplication1
{
public class Chat : Hub
{
public void Send(String message)
{
// Call the addMessage methods on all clients
Clients.addMessage(message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的客户页面
<script type="text/javascript">
$(function () {
//Proxy created on the fly
var chat = $.connection.chat;
// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) { …Run Code Online (Sandbox Code Playgroud) 我有多个SignalR'服务'正在运行,只有一个UI可以访问它们.
如何让客户端js与不同Url的多个连接通信?因为看起来我只能为$ .connection.hub指定一个url,而且我不能使用多个'signalr/hubs'客户端脚本.
有帮助吗?谢谢.
我有一个非常令人沮丧的问题,我似乎无法深究.
我正在使用SignalR将消息推送到移动设备,并且多次触发客户端方法.当我退出时应该清除/关闭/停止连接时,它发出的次数会增加.
我的中心如下所示
public class MyHub:Hub
{
private static string _groupIdentifier = "Test"
public override Task OnConnected()
{
var identity = //grab identity from auth provider
Groups.Add(Context.ConnectionId, string.Format("{0}-{1}", _groupIdentifier, identity.UserId));
return base.OnConnected();
}
public void OnMessageCreated(Message message)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MessageCreatedEmitter>();
context.Clients.Group(String.Format("{0}-{1}",_groupIdentifier, message.userId)).onMessageCreated(obj);
}
public override Task OnReconnected()
{
var identity = //grab identity from my auth provider
Groups.Add(Context.ConnectionId, string.Format("{0}-{1}", _groupIdentifier, identity.UserId));
return base.OnReconnected();
}
public override Task OnDisconnected(bool stopCalled)
{
var identity = //grab identity from my auth …Run Code Online (Sandbox Code Playgroud) 我有一个asp.net经典网站.我已经有了SignalR基本功能(一个客户端向其他客户端发送消息).但现在我只想将消息发送到特定的connectionID.
我的中心:
** [HubName("chatHub")]
public class ChatHub : Hub
{
public static List<string> messages = new List<string>();
public void GetServiceState()
{
Clients.updateMessages(messages);
}
public void UpdateServiceState()
{
messages.Add(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"));
Clients.updateMessages(messages);
}
}**
Run Code Online (Sandbox Code Playgroud)
Asp代码:
<script type="text/javascript">
$(function () {
// creates a proxy to the health check hub
var healthCheckHub = $.connection.chatHub;
console.log($.connection.hub)
// handles the callback sent from the server
healthCheckHub.updateMessages = function (data) {
$("li").remove();
$.each(data, function () {
$('#messages').append('<li>' + this + '</li>');
console.log($.connection);
});
};
$("#trigger").click(function () …Run Code Online (Sandbox Code Playgroud) 这是我的Hub代码:
public class Pusher : Hub, IPusher
{
readonly IHubContext _hubContext = GlobalHost.ConnectionManager.GetHubContext<Pusher>();
public virtual Task PushToOtherInGroup(dynamic group, dynamic data)
{
return _hubContext.Clients.Group(group).GetData(data);
}
}
Run Code Online (Sandbox Code Playgroud)
我想用这段代码在另一个项目中调用此方法:
var pusher = new Pusher.Pusher();
pusher.PushToOtherInGroup("Test", new {exchangeTypeId, price});
Run Code Online (Sandbox Code Playgroud)
我想要调用PushToOtherInGroup,在调用方法时我没有得到任何错误.但是推送器不起作用.
这是我的Ui代码:
$(function() {
hub = $.connection.pusher;
$.connection.hub.start()
.done(function() {
hub.server.subscribe('newPrice');
console.log('Now connected, connection ID=' + $.connection.hub.id);
})
.fail(function() { console.log('Could not Connect!'); });
});
(function() {
hub.client.GetData = function (data) {
debugger;
};
});
Run Code Online (Sandbox Code Playgroud)
我的问题是什么?
是否有推荐的方法在两个应用程序之间共享SignalR集线器?
实际情况是面向公众的WebAPI项目和内部MVC WebApp.我想做的是从WebAPI项目调用SignalR集线器上的方法,并将这些方法的结果推送到通过MVC应用程序连接的客户端.
最好的选择是创建第三个"Hub"项目并让两个项目连接到那个项目吗?如果是这样,如何管理集线器实例?两个应用程序是否可以从不同的应用程序池(以及可能的主机)获取对同一集线器的引用?
我读了一下GlobalHost.ConnectionManager.GetHubContext,这是否足以让两个应用程序都可以使用一个有效的单例集线器?
任何想法都非常感激.
这就是我做的.
问题是没有找到/ signalr/hubs(抛出404).
我的项目有区域,结构如下所示:
signalR的所有脚本都在Scripts文件夹中,我的SignalRTestController.cs看起来像这样:
namespace SignalRTest.Controllers
{
public class SignalRTestController : Controller
{
public ActionResult Index()
{
// Do some work here
// Broadcasting over a Hub from outside of a Hub
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.say("Hello SignalR!");
return View();
}
}
[HubName("MyHub")]
public class MyHub : Hub
{
public void Say(string message)
{
Clients.sendMessage(message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
任何我的Index.cshtml都引用了所有的javascripts和/ signalr/hubs,如下所示://其他Javascripts
script type …