我想使用SignalR
来识别Jquery
上的WCF service
客户端,并在没有请求的情况下向他发送消息。 (即在客户端发送给服务的第一个请求之后,服务可以知道他并向他发送消息)。
我不知道这是否是最好的方法,但这是我能找到的全部。 (仅限VS 2012中支持的WebSocket除外)。
我在服务的Global
文件中添加了以下功能:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}
我创建了Chat.cs:
public class Chat : Hub
{
public void Send(string message)
{
// Call the addMessage method on all clients
Clients.All.addMessage(message);
}
}
在JS
项目中,我添加了JS
的{{1}}个文件:
SignalR
使用它的功能:
<script src="../JavaScript/jquery.signalR-1.1.2.min.js" type="text/javascript"></script>
<script src="/signalr/hubs" type="text/javascript"></script>
这对我来说是新鲜事,如果问题愚蠢,那对不起,但JS的SignalR应该如何知道服务,我应该在哪里定义他? (这需要跨域)
(变量function Chat() {
$(function () {
// Proxy created on the fly
var chat = $.connection.chat;
// Declare a function on the chat hub so the server can invoke it
chat.client.addMessage = function (message) {
alert(message);
};
// Start the connection
$.connection.hub.start().done(function () {
// Call the chat method on the server
chat.server.send('aa');
});
});
}
未定义)
我确定我错过了一些事情,特别是他如何通过SignalR 链接服务和JS的主要内容?
答案 0 :(得分:2)
我缺少的是使用 SignalR with cross-domain 。
在全局文件中,我更改了代码:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs(new HubConfiguration() { EnableCrossDomain = true });
}
这里需要注意的是,由于我使用跨域,因此Application_BeginRequest
函数中的代码应该在完成后取消SignalR
请求它不起作用 。所以我这样取消了它:
protected void Application_BeginRequest(object sender, EventArgs e)
{
//Here is testing whether this request SignalR, if not I do the following code
if (HttpContext.Current.Request.Path.IndexOf("signalr") == -1)
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, x-requested-with");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
}
在客户端:
我添加了SignalR
和Jquery
的脚本,并删除了此脚本:
<script src="/signalr/hubs" type="text/javascript"></script>
由于存在跨域调用,因此不需要。
连接在以下功能中:
var connection;
var contosoChatHubProxy;
function RegisterToServiceMessege() {
connection = $.hubConnection();
connection.url = 'http://localhost:xxx/signalr';
contosoChatHubProxy = connection.createHubProxy('ChatHub');
//This part happens when function broadcastMessage is activated(from the server)
contosoChatHubProxy.on('broadcastMessage', function (userName, message) {
alert('You have a messege:\n' + userName + ' ' + message);
});
connection.start()
.done(function () {
console.log('Now connected, connection ID=' + connection.id);
})
.fail(function () { console.log('Could not connect'); });
}
服务器上的Chat.cs:
[HubName("ChatHub")]
public class Chat : Hub
{
[HubMethodName("Send")]
public void Send(string name, string message)
{
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message);
}
}
从一位客户拨打电话Send
如下:
function SendMessege() {
contosoChatHubProxy.invoke('Send', 'aaa', 'bbb').done(function () {
console.log('Invocation of NewContosoChatMessage succeeded');
}).fail(function (error) {
console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
});
}
所有客户都会收到已发送的邮件。
(您可以通过同时运行多个浏览器来检查这一点。)
答案 1 :(得分:1)
从SignalR的2.0版开始,您无法再使用此代码启用Cors:
protected void Application_Start(object sender, EventArgs e) {RouteTable.Routes.MapHubs(new HubConfiguration() { EnableCrossDomain = true });}
相反,您必须在Startup类初始化方法中添加这两行:
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
而且,对于每个人来说可能并不明显,如果您不想使用其自托管库托管SignalR,那么请记住将项目更改为WebApplication。就我而言,我试图将Signalr附加到WCFProject。并且运行时甚至不会使用此Startup的Configuration方法,从而导致持续错误以禁止访问信号器资源