我有一个SignalR 2.1.1强类型集线器,客户端调用服务器集线器方法,在该方法中,广播被发送到客户端(在我的测试用例中,它只是被调用的调用者) .
hub方法没有返回值( async public Task Test()
) . 从服务器端看,hub方法似乎没有异常 . 在客户端,我得到 Error: Failed at parsing response: {"C":"d-4336366B-A,0|B,1|C,2|D,0|E,0","M":[{
和 Clearing hub invocation callbacks with error: Connection was disconnected before invocation result was received.
在完全发送响应之前,似乎连接已终止 .
问题出现在Windows 7上的Chrome中,但不会出现在IE 11中 .
Simplified Hub Class
public class MessengerHub : Hub<IMessengerClient>, IMessengerHub
{
async Task IMessengerHub.TestActivityNotification()
{
ConnectionInfo info = _connectionInfo[_hub.Context.ConnectionId];
Activity activity = new Activity
{
ActivityId = Guid.NewGuid(),
ContactId = info.UserId,
DateTime = DateTime.UtcNow,
DeviceId = info.DeviceId,
Kind = ActivityKind.Message,
SubKind = ActivitySubKind.MessageSent
};
// This code is actually in another method, just simplifying for demo
await Task task = Task.Run(() =>
{
// I thought the problem might be with the groups...
//Clients.Group(userId.ToString()).OnActivity(activity);
foreach (ConnectionInfo info in _connectionInfo.Values.Where(ci => ci.UserId == userId))
{
Clients.Client(info.ConnectionId).OnActivity(activity);
}
});
}
}
如果我注释掉上面对OnActivity的调用,问题就会消失 .
JavaScript初始化代码
这是来自Razor页面,所以请注意Razor语法 .
//-----------------------------------------------------------------------------
// SignalR Initialization
//-----------------------------------------------------------------------------
$(function () {
// ------------------------------------------
// Set up the client side of the hub
// ------------------------------------------
var messengerHub = $.connection.messengerHub;
var hub = $.connection.hub;
radarMessenger.hub = messengerHub;
radarMessenger.signalr = {
stateConversion: {0: 'connecting', 1: 'connected', 2: 'reconnecting', 4: 'disconnected'}
};
messengerHub.client.onActivity = radarMessenger.onActivity;
// ------------------------------------------
// Connect to the hub
// ------------------------------------------
@{
Activity context = SecurityUtils.GetContext();
}
hub.qs = {
deviceId: '@context.DeviceId',
userId: '@context.ContactId'
};
hub.logging = true;
hub.starting(function() {
console.log("SignalR: Starting");
});
hub.received(function(data) {
console.log("SignalR: Received: " + JSON.stringify(data));
});
hub.connectionSlow(function() {
console.log("SignalR: Connection slow");
});
hub.reconnecting(function() {
console.log("SignalR: Reconnecting");
});
hub.stateChanged(function(data) {
console.log("SignalR: State changed from " +
radarMessenger.signalr.stateConversion[data.oldState] + " to " +
radarMessenger.signalr.stateConversion[data.newState] );
});
hub.disconnected(function() {
console.log("SignalR: Disconnected");
});
hub.error(function (error) {
console.log("SignalR: Error: " + error );
});
hub.start()
.done(function(){ console.log('Now connected, connection ID=' + hub.id); })
.fail(function(){ console.log('Could not Connect!'); });
$("#TestActivityNotification").click(function () {
console.log('TestActivityNotification');
messengerHub.server.testActivityNotification()
.done(function () {
console.log("Called testActivityNotification successfully");
})
.fail(function (error) {
console.log("Error in testActivityNotification: " + error);
});
});
});
Chrome开发者控制台
SignalR: State changed from disconnected to connecting 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:397
SignalR: Client subscribed to hub 'messengerhub'. jquery.signalR-2.1.1.js:81
SignalR: Starting 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:380
SignalR: Negotiating with '/securemessaging/signalr/negotiate?clientProtocol=1.4&deviceId=a60aea91-1d79-4881-943d-1fbf3cb8ba4e&userId=2deb491a-c4f6-4f99-b653-aac65450c3db&connectionData=%5B%7B%22name%22%3A%22messengerhub%22%7D%5D'. jquery.signalR-2.1.1.js:81
SignalR: Attempting to connect to SSE endpoint 'https://dev01.myradarconnect.com:13004/securemessaging/signalr/connect?tran…Uo10Wpetj&connectionData=%5B%7B%22name%22%3A%22messengerhub%22%7D%5D&tid=7'. jquery.signalR-2.1.1.js:81
SignalR: EventSource connected. jquery.signalR-2.1.1.js:81
SignalR: serverSentEvents transport selected. Initiating start request. jquery.signalR-2.1.1.js:81
SignalR: The start request succeeded. Transitioning to the connected state. jquery.signalR-2.1.1.js:81
SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332 and a connection lost timeout of 20000. jquery.signalR-2.1.1.js:81
SignalR: State changed from connecting to connected 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:397
Now connected, connection ID=64188d16-5abe-4e67-9393-10eb59862f82 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:411
TestActivityNotification 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:415
SignalR: Invoking messengerhub.TestActivityNotification jquery.signalR-2.1.1.js:81
SignalR: Error: Error: Failed at parsing response: {"C":"d-4336366B-A,0|B,1|C,2|D,0|E,0","M":[{ 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:407
SignalR: Stopping connection. jquery.signalR-2.1.1.js:81
SignalR: State changed from connected to disconnected 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:397
SignalR: EventSource calling close(). jquery.signalR-2.1.1.js:81
SignalR: Fired ajax abort async = true. jquery.signalR-2.1.1.js:81
SignalR: Stopping the monitoring of the keep alive. jquery.signalR-2.1.1.js:81
SignalR: Clearing hub invocation callbacks with error: Connection was disconnected before invocation result was received.. jquery.signalR-2.1.1.js:81
SignalR: messengerhub.TestActivityNotification failed to execute. Error: Connection was disconnected before invocation result was received. jquery.signalR-2.1.1.js:81
Error in testActivityNotification: Error: Connection was disconnected before invocation result was received. 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:421
SignalR: Disconnected 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:403
SignalR: Received: {"$id":"4","$type":"Microsoft.AspNet.SignalR.Hubs.HubResponse, Microsoft.AspNet.SignalR.Core","I":"0"} 105b20f2-2a6a-46da-83ae-35c32b82eba1?Archived=True:384
更新2014-09-24自定义JsonSerializer
基于@ halter73的答案,我正在更新说我确实使用自定义JsonSerializerSettings . 我会搞砸那些并更新 . 他们来了:
private static void ConfigureJsonFormatter()
{
JsonSerializerSettings jsonSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
jsonSettings.Formatting = Formatting.Indented;
jsonSettings.TypeNameHandling = TypeNameHandling.Objects;
jsonSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
jsonSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
JsonSerializer serializer = JsonSerializer.Create(jsonSettings);
GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);
}
我正在使用实体框架,需要调整一些JSON序列化设置,以避免实体序列化,Web API,MVC和SignalR中的一些问题 .
1 回答
根据日志中的以下行:
看起来您正在使用自定义JsonSerializer . 如果你're not careful, because SignalR relies on some default behavior. For example, JSON payloads must be only one line to work with SignalR' s server-sent events transport,这可能会有问题 .
Chrome支持使用服务器发送事件所需的EventSource API,但IE不支持 . 这可能是您只看到Chrome问题的原因 .