我有一个简单的SignalR中心应用程序,在服务器端使用MVC4 / C#,托管在Azure Web角色(单个实例,在模拟器中,带有http输入端点),并在客户端上编译为JS的TypeScript。我有一个图像库,许多客户可以上传到,当有人上传时,我希望任何其他连接的客户端收到一条消息,告诉他们这已经发生并让他们有机会刷新,类似于你收到通知的方式关于你在SO上看到的问题的新答案。
在服务器上,我有一个返回图库中项目列表的方法,以及另一种将消息推送到客户端的方法,如下所示:
public virtual void PushMessage(String message)
{
System.Diagnostics.Debug.WriteLine("PushMessage: " + message);
this.Clients.All.pushMessage(message);
}
public virtual GalleryDataResponse<T> List(String accountID, String armID, Int32 page)
{
GalleryDataResponse<T> response = new GalleryDataResponse<T>();
try
{
IEnumerable<T> items = getAllItems(accountID, armID, page);
if (items != null && items.Count() > 0)
{
response.Result = DataResponse.RESULT_DATA;
response.Message = String.Empty;
response.Items = items;
}
else
{
response.Result = DataResponse.RESULT_EMPTY;
response.Message = @"There are no " + itemName + @"s in your account at the moment: " + this.Context.ConnectionId;
response.Items = null;
}
this.Caller.pushMesage("HELLO, CALLER");
PushMessage("HELLO, ALL CLIENTS");
}
catch (Exception ex)
{
response.Result = DataResponse.RESULT_ERROR;
response.Message = ex.Message;
response.Items = null;
}
return response;
}
(List
函数然后在传递类型T
的派生类中被覆盖 - 这很好用。)
在客户端上,使用DefinitelyTyped中的SignalR定义文件,我有以下TypeScript:
var that = this;
this.connection = $.hubConnection();
this.connection.logging = true;
this.connection.id = this.gServerData.CurrentAccountID + "-" + this.gServerData.CurrentArmID;
this.connection.start().done(() => {
that.proxy = that.connection.createProxy(that.gServerData.DataHubName);
that.proxy.on("pushMessage", (message) => {
console.log("PUSHED: " + message);
debugger;
});
that.proxy.invoke("List", that.gServerData.CurrentAccountID, that.gServerData.CurrentArmID, 0).done((response: IGalleryDataResponse) => {
that.handleListResponse(response);
});
});
...提供以下JavaScript:
var that = this;
this.connection = $.hubConnection();
this.connection.logging = true;
this.connection.id = this.gServerData.CurrentAccountID + "-" + this.gServerData.CurrentArmID;
this.connection.start().done(function () {
that.proxy = that.connection.createProxy(that.gServerData.DataHubName);
that.proxy.on("pushMessage", function (message) {
t.Tracer.Trace("PUSHED: " + message);
});
that.proxy.invoke("List", that.gServerData.CurrentAccountID, that.gServerData.CurrentArmID, 0).done(function (response) {
that.handleListResponse(response);
});
});
调用我的列表函数非常有效。我完全按照预期从集线器收到回复。如果我终止服务器进程但让浏览器保持活动状态,我会在控制台中收到错误,告诉我客户端正在尝试维护连接。
我将这两行this.Caller.pushMesage("HELLO, CALLER"); PushMessage("HELLO, ALL CLIENTS");
添加到服务器端的List函数中,以测试服务器将内容推送到客户端。我希望在list函数返回之前调用它们,但这不会发生。我也试过从外面打电话给中心,如下:
var myHub = GlobalHost.ConnectionManager.GetHubContext<MediaGalleryHub>();
myHub.Clients.pushMessage("Hello from Global.asax");
...虽然我可以通过跟踪看到我的PushMessage函数被调用,但我从来没有在客户端获得任何东西。
我做错了什么?
我已经尝试过的参考文献包括:
http://msdn.microsoft.com/en-us/magazine/hh965663.aspx
https://github.com/SignalR/SignalR/wiki/Hubs
https://github.com/SignalR/SignalR/wiki/SignalR-JS-Client-Hubs-%28No-Proxy%29
答案 0 :(得分:4)
这段代码错了:
this.connection.start().done(() => {
that.proxy = that.connection.createProxy(that.gServerData.DataHubName);
that.proxy.on("pushMessage", (message) => {
console.log("PUSHED: " + message);
debugger;
});
that.proxy.invoke("List", that.gServerData.CurrentAccountID, that.gServerData.CurrentArmID, 0).done((response: IGalleryDataResponse) => {
that.handleListResponse(response);
});
});
您需要在致电开始之前订阅:
that.proxy = that.connection.createProxy(that.gServerData.DataHubName);
that.proxy.on("pushMessage", (message) => {
console.log("PUSHED: " + message);
debugger;
});
this.connection.start().done(() => {
that.proxy.invoke("List", that.gServerData.CurrentAccountID, that.gServerData.CurrentArmID, 0).done((response: IGalleryDataResponse) => {
that.handleListResponse(response);
});
});