我有一个托管我网站的网络服务器。我有一个运行某个任务的单独服务器。一旦有结果我想ping我当前登录我的网络服务器的客户端。这应该使用SignalR
完成此设置没有服务运行服务器正在运行:
我有一个单独的项目来托管我的中心:
public class NotificationHub : Hub
{
public string Activate() { return ""; }
public override Task OnConnected()
{
string username = Context.User.Identity.Name.ToLower();
Groups.Add(Context.ConnectionId, username);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
return base.OnDisconnected(stopCalled);
}
public override Task OnReconnected()
{
return base.OnReconnected();
}
}
和客户端(此代码在登录时执行)
var notificationHub = $.connection.notificationHub;
notificationHub.client.connected = function () { console.log('client connected fired!'); };
$.connection.hub.start().done(function () {
notificationHub.server.activate();
})
notificationHub.client.testPing = function (message) {
console.log("Message received: "+message);
};
然后我有一个名为BubbleController with control
的控件public ActionResult NotifyPing(string username, string message)
{
SignalRfunctions.TestPing(username,message);
return Content("OK");
}
其中SignalRFunction是一个包含所有通信函数的静态类,它被封装在一个名为Notifications的单独项目中
public class SignalRfunctions
{
public static void TestPing(string username, string message)
{
IHubContext signalR = GlobalHost.ConnectionManager.GetHubContext<NotificationHub.NotificationHub>();
signalR.Clients.Group(username).TestPing(message);
}
}
现在,当我编译所有内容时,以Bob身份登录并在浏览器控制台中执行此命令
$.get('/bubble/notifyping?username=bob&message=hi',function(){});
我在控制台中收到回复:
收到的消息:您好
这是预期的(查看客户端signalR支持)
现在什么不起作用:
当我打电话
SignalRfunctions.TestPing("bob"," hello from jobrunner");
来自我的服务(非网络相关项目),即使我以bob身份登录,我的浏览器控制台也没有得到任何回复。基本上,SignalR在我的web-appliactioin中为我工作,当我尝试与我的服务器运行服务桥接时,我没有连接。
我做错了什么?
(我确实在调试下运行了所有内容以检查是否有任何明显的错误,但没有找到任何错误)
更新:在最初的问题中,我错过了一段初始化SignalR的代码,它是:
[assembly: OwinStartup(typeof(WebApp.OwinStartup))]
namespace WebApp
{
public class OwinStartup
{
public void Configuration(IAppBuilder app)
{
UsernameProvider usernameProvider = new UsernameProvider();
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => usernameProvider);
app.MapSignalR();
}
}
}
其中UsernameProvider类在这里:
public class UsernameProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
string username = request.User.Identity.Name.ToLower();
return username;
}
}
答案 0 :(得分:2)
除启动例程外,您显示的大部分服务器逻辑都已显示。 它是你连接客户听的路径的地方。 我也不知道你在哪里告诉客户端在连接服务器时应该看到的位置,但是因为它回到服务器我猜你是否成功指出了它。
http://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection
甚至在这里http://www.asp.net/signalr/overview/deployment/tutorial-signalr-self-host
[assembly: OwinStartup(typeof(Startup))]
namespace YourSignalR
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
// Debugging only
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
// custom path for clients to listen to. By default it is /signalr
app.MapSignalR(Resources.Url, hubConfiguration);
}
}
}
更新 - 我一直很忙。
根据您的说法,您有一个Web服务器作为SignalR服务器和一个与之通信的Web客户端。您希望拥有一个单独的基于SOA的解决方案,该解决方案要么具有服务,要么调用其他服务。您希望服务解决方案能够与SignalR Web服务器联系。
根据您的说法,我不相信您从服务解决方案中联系的HubContext与Web客户端连接的上下文相同,因此它没有当你告诉它发送信息时,一个接触到。你可以调试并检查我相信的两个身份。
我熟悉的有两种方法可以帮到你。
如果您希望自己可以使用服务后端实现的自托管SingalR服务器。我使用它来让WPF客户端接收来自内部服务和外部Web服务的服务调用的更新。
另一种方法是您可以将您的服务项目视为另一个客户端,并通过SignalR与Web服务器联系以与其他客户端/组进行通信。这样他们都是同步的,并且处于相同的背景下。因此,服务器想要发送的任何内容都只是从Web服务器调用一个方法来告诉其他客户端/组。
如果我想到别的什么,我会发布它。
我做了一个快速的例子,如果你想使用这种方法,我使用Clients.All而不是设置组,使其更简单,并显示它的工作原理。
网页部分 中心
namespace SignalRChatter
{
/// <summary>
/// install-package Microsoft.AspNet.SignalR
/// </summary>
public class ChatHub : Hub
{
public void Send(string name, string message)
{
Clients.All.broadcastMessage(name, message);
}
}
}
启动
[assembly: OwinStartup(typeof(SignalRChatter.Startup))]
namespace SignalRChatter
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application,
// visit http://go.microsoft.com/fwlink/?LinkID=316888
app.MapSignalR();
}
}
}
HTML正文
<body>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<input type="hidden" id="displayname" />
<ul id="discussion"></ul>
</div>
<!--Script references. -->
<!--Reference the jQuery library. you are using -->
<script src="Scripts/jquery-2.1.1.min.js"></script>
<!--Reference the SignalR library. you are using-->
<script src="Scripts/jquery.signalR-2.1.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. you are using -->
<script src="signalr/hubs"></script>
<!--Add script to update the page and send messages.-->
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
</script>
</body>
服务器端像客户端一样行事 您在控制台中输入的任何内容都将发送到Web客户端。 您可能会调用专门用于后端客户端的方法来与Web客户端进行通信。由你决定。
确保安装此软件包: 此软件包支持.NET 4和.NET 4.5的WinRT,Silverlight,WPF,控制台应用程序和Windows Phone客户端。 PM&GT;安装包Microsoft.AspNet.SignalR.Client
namespace SomeConsoleApp
{
class Program
{
//PM> Install-Package Microsoft.AspNet.SignalR.Client
static void Main(string[] args)
{
var hubConnection = new HubConnection("http://localhost:YOURPORT/");
IHubProxy chatHubProxy = hubConnection.CreateHubProxy("ChatHub");
// it doesn't need to listen to the other clients but was testing to make sure it can. all it needs to do is send to the others.
chatHubProxy.On<string, string>("broadcastMessage", (name, message) => Console.WriteLine("update for {0} new message {1}", name, message));
Connect(hubConnection);
var input = "Server Acting Like A Client";
Console.WriteLine(input);
while (!input.Equals("Exit", StringComparison.InvariantCultureIgnoreCase))
{
input = Console.ReadLine();
Invoker(chatHubProxy, input);
}
Console.ReadLine();
}
static async void Connect(HubConnection hubConnection)
{
try
{
Console.WriteLine("starting");
await hubConnection.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
static async void Invoker(IHubProxy chatHubProxy, string input)
{
await chatHubProxy.Invoke("Send", "Server Client", input);
}
}
}
答案 1 :(得分:1)
如果我理解得很清楚你有1个网络应用程序和另一个应用程序。
您希望在第二个应用程序发生某些事情时,通过signalR向登录到您网站的某人发送消息。
如果是这种情况,您可以使用和httpclient
从应用程序调用您的webapphttp://www.dotnetperls.com/httpclient
到你的端点/ bubble / notifyping传递你想要的信息。