我正在尝试使我的React应用程序和用C#编写的服务器组件之间建立基本的signalR连接。
我已经使用JQuery SignalR库引导了signalR客户端并作为中间件调用。在启动时,它应该尝试并调用唯一可用的服务器方法,然后这将导致构建集线器并调用该方法。但是,不会调用集线器的构造函数,也不会调用被调用的方法。根据客户端连接属性,可以很明显地找到集线器并进行连接,因为在调用onStateChanged()方法时将“ Connected”作为新状态,并且可以在chrome dev工具中查看连接对象。但是,调用服务器方法时,它只会在javascript控制台中给我以下错误(服务器进程上什么都没有发生)
更详细的SignalR错误是
错误:发送失败。↵at Object.error (https://localhost:3830/assets/signalr/jquery.signalR-2.2.0.min.js:8:4512)↵ 在Object.transportError (https://localhost:3830/assets/signalr/jquery.signalR-2.2.0.min.js:8:4627)↵ 在s (https://localhost:3830/assets/signalr/jquery.signalR-2.2.0.min.js:8:18349)↵ 在Object.error (https://localhost:3830/assets/signalr/jquery.signalR-2.2.0.min.js:8:18693)↵ 在我 (https://localhost:3830/assets/signalr/jquery-1.12.0.min.js:2:27451)↵ 在Object.fireWith [作为rejectWith] (https://localhost:3830/assets/signalr/jquery-1.12.0.min.js:2:28215)↵ 在y (https://localhost:3830/assets/signalr/jquery-1.12.0.min.js:4:22617)↵ 在XMLHttpRequest.c (https://localhost:3830/assets/signalr/jquery-1.12.0.min.js:4:26750
在下面的代码中,我在行上中断
const sessionHub = connection[HUB_NAME];
然后让我查看该特定集线器的连接,该集线器已连接并且看起来不错。但是在下面的调用行中,它失败并出现上述错误。
我的客户端中间件代码
import hostlookup from "./hostlookup";
import { LOGTAIL_INCOMING_METHOD_UPDATED, HUB_NAME, SIGNALR_CONNECT, SIGNALR_DISCONNECT, LOGTAIL_ACTION_START, LOGTAIL_ACTION_STOP, LOGTAIL_SERVER_METHOD_STOP, LOGTAIL_SERVER_METHOD_START, SIGNALR_STATE_DISCONNECTED, SIGNALR_STATE_CONNECTING, SIGNALR_STATE_RECONNECTING } from "./constants";
import { getSignalRStatusChangedAction, getSignalRStopAction } from "./actions";
import { getLogTailUpdatedAction } from "../../modules/logtail/actions";
const url = hostlookup().host + '/signalr';
const connection = $.hubConnection(url, {
useDefaultPath: false
});
export default function createSignalrMiddleware() {
return (store) => {
const dispatch = store.dispatch.bind(store);
const SIGNALR_STATES = {
0: 'Connecting',
1: 'Connected',
2: 'Reconnecting',
4: 'Disconnected'
};
let keepAlive = true;
let wasConnected = false;
let currentState = null;
initialiseListeners(dispatch);
function onStateChanged(state) {
if (currentState === state) { return; }
if (currentState === 2 && state === 1) {
connection.start().done(() => {
// reconnect actions if required
});
}
currentState = state;
dispatch(getSignalRStatusChangedAction(state));
}
connection.stateChanged((state) => {
const newStateName = SIGNALR_STATES[state.newState];
if (newStateName === 'Connected') {
wasConnected = true;
}
onStateChanged(state.newState);
});
connection.disconnected(() => {
if (keepAlive) {
if (wasConnected) {
onStateChanged(SIGNALR_STATE_RECONNECTING);
} else {
onStateChanged(SIGNALR_STATE_CONNECTING);
}
connection.start().done(() => {
// Connect actions if required
});
}
});
function initialiseListeners(dispatcher) {
const sessionHub = connection[HUB_NAME] = connection.createHubProxy(HUB_NAME);
sessionHub.on(LOGTAIL_INCOMING_METHOD_UPDATED,
(logDataLine) => {
dispatch(getLogTailUpdatedAction(logDataLine));
})
sessionHub.on('Disconnect', () => dispatcher(getSignalRStopAction()));
}
return (next) => (action) => {
const { type } = action;
const sessionHub = connection[HUB_NAME];
switch (type) {
case SIGNALR_CONNECT:
keepAlive = true;
onStateChanged(SIGNALR_STATE_CONNECTING);
connection.start().done(() => {
const sessionHub = connection[HUB_NAME];
sessionHub.invoke(LOGTAIL_SERVER_METHOD_START, 'test')
// Connect actions if required
});
return;
case SIGNALR_DISCONNECT:
keepAlive = false;
wasConnected = false;
onStateChanged(SIGNALR_STATE_DISCONNECTED);
connection.stop();
return;
case LOGTAIL_ACTION_START:
sessionHub.invoke(LOGTAIL_SERVER_METHOD_START, action.applicationName);
return;
case LOGTAIL_ACTION_STOP:
sessionHub.invoke(LOGTAIL_SERVER_METHOD_STOP);
return;
default:
return next(action);
}
}
}
}
我的服务器中心代码
public interface ILogTailClient
{
void LogDataUpdated(string[] logData);
}
[Authorize]
public class LogTailHub : Hub<ILogTailClient>
{
private readonly IClientConnectionHandler _clientConnectionHandler;
private readonly IAuthorisedUserCache _userCache;
private readonly ILogTailService _logTailService;
public LogTailHub(IClientConnectionHandler clientConnectionHandler, IAuthorisedUserCache userCache, ILogTailService logTailService)
{
_clientConnectionHandler = clientConnectionHandler;
_userCache = userCache;
_logTailService = logTailService;
}
public override Task OnConnected()
{
var clientConnection = GetClientConnection();
if (clientConnection != null)
_clientConnectionHandler.OnConnected(clientConnection);
return base.OnConnected();
}
public override Task OnReconnected()
{
lock (_clientConnectionHandler)
{
_clientConnectionHandler.OnDisconnected(Context.ConnectionId);
var clientConnection = GetClientConnection();
if (clientConnection != null)
_clientConnectionHandler.OnConnected(clientConnection);
}
return base.OnReconnected();
}
public override async Task OnDisconnected(bool stopCalled)
{
_clientConnectionHandler.OnDisconnected(Context.ConnectionId);
StopTailing();
await base.OnDisconnected(stopCalled);
}
public void StartTailing(string applicationName)
{
_logTailService.StartListening(Context.ConnectionId, applicationName);
}
public void StopTailing()
{
_logTailService.StopListening(Context.ConnectionId);
}
private IClientConnection GetClientConnection()
{
if (Context.User != null && _userCache.TryGetUser(Context.User.Identity.Name, out var authorisedUser))
{
return new ClientConnection(Context.ConnectionId, authorisedUser);
}
return null;
}
}
中心的DI注册
public class WebNotificationsModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(GetType().Assembly).AsImplementedInterfaces()
.Except<LogTailHub>() // Defined below
.Except<HubContextProvider>(); // Defined as Singleton below
var hubConfiguration = new HubConfiguration
{
EnableJavaScriptProxies = false,
EnableDetailedErrors = true
};
builder.Register(ctx => hubConfiguration);
builder.Register(ctx => {
var connectionManager = hubConfiguration.Resolver.Resolve<IConnectionManager>();
return connectionManager.GetHubContext<LogTailHub, ILogTailClient>();
}).ExternallyOwned();
builder.RegisterType<HubContextProvider>().As<IHubContextProvider>().SingleInstance();
builder.RegisterType<LogTailHub>().ExternallyOwned(); // SignalR hub registration
var serializer = new JsonSerializer();
serializer.Converters.Add(new StringEnumConverter());
builder.RegisterInstance(serializer).As<JsonSerializer>();
}
}
答案 0 :(得分:0)
SignalR正在调用的服务器端代码引发异常,您需要此异常的详细信息以将代码指向何处。详细信息应在您的服务器事件日志中。另外,您可以(临时)打开详细错误,这会将异常详细信息推送到JavaScript控制台中。
在Startup.cs中:
hubConfiguration.EnableDetailedErrors = true;
如果您选择这种方法,请确保在部署之前关闭详细的错误。