我使用 create-react-app 来构建初始反应应用程序。
我的 DashBoard 组件:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import $ from 'jquery';
import 'signalr';
class Dashboard extends Component {
constructor(props) {
super(props);
var connection = $.hubConnection('http://[address]:[port]');
var proxy = connection.createHubProxy('[hubname]');
// atempt connection, and handle errors
connection.start()
.done(function(){ console.log('Now connected, connection ID=' + connection.id); })
.fail(function(){ console.log('Could not connect'); });
}
render() {
return (...);
}
}
export default Dashboard;
现在我从SignalR得到以下错误,说没有添加jQuery,但我已将其导入上面的行:
错误:找不到jQuery。请确保之前引用了jQuery SignalR客户端JavaScript文件。
如果我注释掉导入" signalr&#34 ;; jQuery正确加载,我可以访问模块内的$
。为什么会这样?
答案 0 :(得分:14)
这就是我们现在(2020年)使用新软件包@ microsoft / signalr的方式。 我们使用Redux,但是您不必使用Redux就能使用此方法。
如果您使用@ microsoft / signalr软件包而不是@ aspnet / signalr,则可以通过这种方法进行设置。这是我们在prod中的工作代码:
import {
JsonHubProtocol,
HubConnectionState,
HubConnectionBuilder,
LogLevel
} from '@microsoft/signalr';
const isDev = process.env.NODE_ENV === 'development';
const startSignalRConnection = async connection => {
try {
await connection.start();
console.assert(connection.state === HubConnectionState.Connected);
console.log('SignalR connection established');
} catch (err) {
console.assert(connection.state === HubConnectionState.Disconnected);
console.error('SignalR Connection Error: ', err);
setTimeout(() => startSignalRConnection(connection), 5000);
}
};
// Set up a SignalR connection to the specified hub URL, and actionEventMap.
// actionEventMap should be an object mapping event names, to eventHandlers that will
// be dispatched with the message body.
export const setupSignalRConnection = (connectionHub, actionEventMap = {}, getAccessToken) => (dispatch, getState) => {
const options = {
logMessageContent: isDev,
logger: isDev ? LogLevel.Warning : LogLevel.Error,
accessTokenFactory: () => getAccessToken(getState())
};
// create the connection instance
// withAutomaticReconnect will automatically try to reconnect
// and generate a new socket connection if needed
const connection = new HubConnectionBuilder()
.withUrl(connectionHub, options)
.withAutomaticReconnect()
.withHubProtocol(new JsonHubProtocol())
.configureLogging(LogLevel.Information)
.build();
// Note: to keep the connection open the serverTimeout should be
// larger than the KeepAlive value that is set on the server
// keepAliveIntervalInMilliseconds default is 15000 and we are using default
// serverTimeoutInMilliseconds default is 30000 and we are using 60000 set below
connection.serverTimeoutInMilliseconds = 60000;
// re-establish the connection if connection dropped
connection.onclose(error => {
console.assert(connection.state === HubConnectionState.Disconnected);
console.log('Connection closed due to error. Try refreshing this page to restart the connection', error);
});
connection.onreconnecting(error => {
console.assert(connection.state === HubConnectionState.Reconnecting);
console.log('Connection lost due to error. Reconnecting.', error);
});
connection.onreconnected(connectionId => {
console.assert(connection.state === HubConnectionState.Connected);
console.log('Connection reestablished. Connected with connectionId', connectionId);
});
startSignalRConnection(connection);
connection.on('OnEvent', res => {
const eventHandler = actionEventMap[res.eventType];
eventHandler && dispatch(eventHandler(res));
});
return connection;
};
然后您将按以下方式致电。请注意,这是一个伪代码。根据项目设置,您可能必须使用不同的名称。
import { setupSignalRConnection } from 'fileAbove.js';
const connectionHub = '/hub/service/url/events';
export const setupEventsHub = setupSignalRConnection(connectionHub, {
onMessageEvent: someMethod
}, getAccessToken);
export default () => dispatch => {
dispatch(setupEventsHub); // dispatch is coming from Redux
};
让我知道是否对投票有帮助。谢谢
答案 1 :(得分:3)
我发现信号员依赖于window.jQuery
。出于某种原因import $ from 'jquery'
没有设置window.jQuery
。这就是为什么需要明确地做到这一点。
我用这种方式解决了这个问题:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import $ from 'jquery';
window.jQuery = $;
require('signalr');
class Dashboard extends Component {
// .....
}
export default Dashboard;
答案 2 :(得分:3)
更新:请注意,如果您在ReactJS应用中使用Redux,则以下解决方案不一定是最佳解决方案。 It is better to implement signalR as a middleware. You can find the best answer here.
如果您不使用Redux,或者您仍想在React组件中实现它,请继续阅读: 对于使用最新版本的signalR(核心v2.1)的用户,由于jQuery不再是signalR的依赖项,因此可以将其导入:
import * as signalR from '@aspnet/signalr';
然后像这样使用它:
signalR.HubConnectionBuilder()
这里是一个例子:
import React, { PureComponent } from 'react';
import { string } from 'prop-types';
import * as signalR from '@aspnet/signalr';
class SignalR extends PureComponent {
constructor (props) {
super(props);
this.connection = null;
this.onNotifReceived = this.onNotifReceived.bind(this);
}
componentDidMount () {
const protocol = new signalR.JsonHubProtocol();
const transport = signalR.HttpTransportType.WebSockets;
const options = {
transport,
logMessageContent: true,
logger: signalR.LogLevel.Trace,
accessTokenFactory: () => this.props.accessToken,
};
// create the connection instance
this.connection = new signalR.HubConnectionBuilder()
.withUrl(this.props.connectionHub, options)
.withHubProtocol(protocol)
.build();
this.connection.on('DatabaseOperation', this.onNotifReceived);
this.connection.on('DownloadSession', this.onNotifReceived);
this.connection.on('UploadSession', this.onNotifReceived);
this.connection.start()
.then(() => console.info('SignalR Connected'))
.catch(err => console.error('SignalR Connection Error: ', err));
}
componentWillUnmount () {
this.connection.stop();
}
onNotifReceived (res) {
console.info('Yayyyyy, I just received a notification!!!', res);
}
render () {
return <span />;
};
};
SignalR.propTypes = {
connectionHub: string.isRequired,
accessToken: string.isRequired
};
export default SignalR;
答案 3 :(得分:1)
签出SignalR no jQuery
npm i -D signalr-no-jquery
import { hubConnection } from 'signalr-no-jquery';
const connection = hubConnection('http://[address]:[port]', options);
const hubProxy = connection.createHubProxy('hubNameString');
// set up event listeners i.e. for incoming "message" event
hubProxy.on('message', function(message) {
console.log(message);
});
// connect
connection.start({ jsonp: true })
.done(function(){ console.log('Now connected, connection ID=' + connection.id); })
.fail(function(){ console.log('Could not connect'); });