im trying to implement alerts from backed to my React front with signalr, but actually the client connect successful but not receive alerts(messages) when I send from the backend:
Backend .net 6:
Interface:
namespace BucciaratiMessenger.Hubs
{
public interface IAlertClient
{
Task ReceiveAlert(Alert alert);
}
}
Hub:
namespace BucciaratiMessenger.Hubs
{
public class AlertHub : Hub<IAlertClient>
{}
}
Program:
builder.Services.AddSignalR();
builder.Services.AddCors(options =>
{
options.AddPolicy("ClientPermission", policy =>
{
policy.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("http://localhost:3000")
.AllowCredentials();
});
});
var app = builder.Build();
app.MapHub<AlertHub>("hubs/alert");
Controller:
[Produces("application/json")]
[ApiController]
[Route("api/[controller]")]
public class AlertController :Controller
{
private readonly IHubContext<AlertHub, IAlertClient> _alertHub;
public AlertController(IHubContext<AlertHub, IAlertClient> alertHub)
{
this._alertHub = alertHub;
}
[Route(nameof(AlertController.RegisterAlert)), HttpPost]
public async Task<IActionResult> RegisterAlert(Alert entity)
{
try
{
await _alertHub.Clients.All.ReceiveAlert(entity);
...
}catch(Exception ex)
{
...
}
}
}
React Client:
const HeaderComp = (props) => {
const[connection, setConnection] = useState(null)
const [ alert, setAlert ] = useState([]);
const latestAlert = useRef(null)
const[countAlert, setCountAlert] = useState(0)
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl('http://localhost:5146/hubs/alert')
.withAutomaticReconnect()
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
if (connection) {
connection.start()
.then(result => {
console.log('Connected!')
connection.on('ReceiveAlert', message => {
const updatedChat = [...latestAlert.current]
updatedChat.push(message)
setAlert(updatedChat)
setCountAlert(countAlert+1)
});
})
.catch(e => console.log('Connection failed: ', e));
}
}, [connection]);
return (
<Layout>
...
</Layout>
)
}
export default HeaderComp
In the Console.log I get success connection to http://localhost:5146/hubs/alert.
When I send to the method controller any message, not occur any exception, but the client not receive the alert.
The problem were the two useEffect, only need one:
useEffect(() => {
const connection = new HubConnectionBuilder()
.withUrl('http://localhost:5146/hubs/alert')
.withAutomaticReconnect()
.build();
connection.start()
.then(result => {
console.log('Connected!');
connection.on('ReceiveAlert', message => {
setCountAlert(countAlert+1)
});
})
.catch(e => console.log('Connection failed: ', e));
}, []);
Related
I'm having below setup in my project, whenever I extends the httpService and use the 'this.instance' in any service I'm getting the error.
If I use axios.get directly without any interceptors in my service files its working fine.
Im new to the unit testing and badly stuck with this. Please share your comments below. It'll be really helpful.
httpClient.ts
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { DEFAULT_HEADERS, HOST } from './ApiHelper';
export abstract class HttpService {
protected readonly instance: AxiosInstance;
public constructor(requestConfig: AxiosRequestConfig) {
this.instance = axios.create(requestConfig);
this.instance.interceptors.request.use((request) => {
request.baseURL = HOST;
request.headers = { ...DEFAULT_HEADERS };
return request;
});
this.instance.interceptors.response.use(
(response) =>
response,
(error) =>
new Promise((resolve, reject) => {
reject(error.response);
}),
);
}
}
export default HttpService;
someService.ts
import HttpService from './HttpService';
const warningListUrl = 'some/url';
class SomeService extends HttpService {
public constructor() {
super({
});
}
public async getSomething(params: any) {
this.instance({
method: 'GET',
url: warningListUrl,
params,
}).then((res) =>
res.data);
}
}
export default SomeService;
ReactComponent.tsx
const fetchList = async () => {
try {
setIsLoading(true);
const someService = new SomeService();
const response: any = await someService.getSomething({});
setWarnings(response.content);
setTotalPages(response.totalPages);
} catch (error) {
console.log(error);
} finally { setIsLoading(false); }
};
useEffect(() => {
fetchList();
}, []);
ReactComponent.test.tsx
jest.mock('../../services/SomeService');
const someService = new SomeService();
describe('page tests', () => {
test('page renders without crashing', async () => {
(someService.getWarningList as jest.Mock).mockResolvedValue(someMatchingData);
await act(async () => {
render(<ReactComponent />);
});
const text = screen.getByText('Warning 1');
expect(text).toBeInTheDocument();
});
}
Error:
TestingLibraryElementError: Unable to find an element with the text: Warning 1. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
render(<Warning />);
});
-> const text = screen.getByText('Warning 1');
expect(text).toBeInTheDocument();
});
You could use requireActual if you need to mock only specific methods.
jest.mock('../../services/SomeService', ()=> {
return {
...jest.requireActual('../../services/SomeService'),
getWarningList: new Promise.resolve(someMatchingData)
}
})
How about mocking a module like this?
Accessing methods through 'prototype' saved my day.
(someService.prototype.getWarningList as jest.Mock).mockResolvedValue(someMatchingData);
just adding it above the test description saved me.
I'm using "#microsoft/signalr": "^6.0.5", and trying to set up a connection.
It is able to connect with the backend, but I am not sure if my setup looks OK for when the connection fails.
Specifically, I am wondering if the last useEffect is correctly written (the placement of the onClose clause)
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(
"https://localhost:3000/workorderHub",
{ accessTokenFactory: () => token, withCredentials: false }
)
.configureLogging(LogLevel.Information)
.withAutomaticReconnect()
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
async function start() {
if (connection) {
try {
connection
.start()
.then(() => {
connection.invoke("SubscribeToProject", projectId); // calling hub method from the client
})
.catch((err) => {
console.error(err.toString());
});
connection.on(
"OperationUpdated",
(projectId, operationId, operation) => {
// function called from the backend Hub
actions.updateSyncedOperation({ operationId, operation });
}
);
} catch (err) {
console.log({ err });
setTimeout(start, 5000);
}
} else {
connection.onclose(async () => {
await start();
});
}
}
start();
}, [connection]);
For React 18 with the new strictMode behaviour i do the following.
It only creates one connection without any errors and it seems to cleanup properly during strictmode behaviour.
export const useLiveUpdates = () => {
const [connectionRef, setConnection] = useState < HubConnection > ();
function createHubConnection() {
const con = new HubConnectionBuilder()
.withUrl(`${EnvService.getUrlHub('url')}`, {
accessTokenFactory: () => AuthService.getToken(),
})
.withAutomaticReconnect()
.build();
setConnection(con);
}
useEffect(() => {
createHubConnection();
}, []);
useEffect(() => {
if (connectionRef) {
try {
connectionRef
.start()
.then(() => {
connectionRef.on('message', () => { ...
});
})
.catch((err) => {
logger.error(`Error: ${err}`);
});
} catch (error) {
logger.error(error as Error);
}
}
return () => {
connectionRef ? .stop();
};
}, [connectionRef]);
};
I have a problem with my asp.net core and reactjs app.
I want to fire OnDisconnected method in backend side but I dont know how and when I can call this method?
This is my react code :
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl('https://localhost:5032/hub/notif',
{
accessTokenFactory: () =>Token
})
.withAutomaticReconnect()
.build();
setConnection(newConnection);
console.log(newConnection);
}, []);
useEffect(async () => {
if (connection) {
connection.start()
.then(result => {
console.log('Connected!');
connection.on('RecieveNotification', message => {
console.log(message);
});
})
.catch(e => console.log('Connection failed: ', e));
}
}, [connection]);
I am using an opensource react project and getting the following error.
does not provide an export named 'default'
Here is the .js file causing the issue.
import { RevAiStreamingClient, AudioConfig } from 'revai-node-sdk';
module.exports = class StreamingClient {
constructor(accessToken, io) {
console.log('Loading Streaming Client');
this.accessToken = accessToken;
this.io = io;
}
start() {
this.revAiStreamingClient = new RevAiStreamingClient(this.accessToken, new AudioConfig('audio/x-wav'));
this.revAiStreamingClient.on('close', (code, reason) => {
console.log(`Connection closed, ${code}: ${reason}`);
});
this.revAiStreamingClient.on('httpResponse', (code) => {
console.log(`Streaming client received http response with code: ${code}`);
});
this.revAiStreamingClient.on('connectFailed', (error) => {
console.log(`Connection failed with error: ${error}`);
});
this.revAiStreamingClient.on('connect', (connectionMessage) => {
console.log(`Connected with job id: ${connectionMessage.id}`);
this.io.emit('streaming-connected', connectionMessage);
});
this.revStream = this.revAiStreamingClient.start();
this.revStream.on('data', (data) => {
this.io.emit('transcript', data);
});
}
end() {
this.revStream = null;
this.revAiStreamingClient.end();
}
stream(data) {
console.log('streaming data ....');
this.revStream && this.revStream.write(data);
}
};
UPDATE:
Fixed it.
import { RevAiStreamingClient, AudioConfig } from 'revai-node-sdk';
class StreamingClient {
constructor(accessToken, io) {
console.log('Loading Streaming Client');
this.accessToken = accessToken;
this.io = io;
}
start() {
this.revAiStreamingClient = new RevAiStreamingClient(this.accessToken, new AudioConfig('audio/x-wav'));
this.revAiStreamingClient.on('close', (code, reason) => {
console.log(`Connection closed, ${code}: ${reason}`);
});
this.revAiStreamingClient.on('httpResponse', (code) => {
console.log(`Streaming client received http response with code: ${code}`);
});
this.revAiStreamingClient.on('connectFailed', (error) => {
console.log(`Connection failed with error: ${error}`);
});
this.revAiStreamingClient.on('connect', (connectionMessage) => {
console.log(`Connected with job id: ${connectionMessage.id}`);
this.io.emit('streaming-connected', connectionMessage);
});
this.revStream = this.revAiStreamingClient.start();
this.revStream.on('data', (data) => {
this.io.emit('transcript', data);
});
}
end() {
this.revStream = null;
this.revAiStreamingClient.end();
}
stream(data) {
console.log('streaming data ....');
this.revStream && this.revStream.write(data);
}
}
export default StreamingClient;
I need to see more of the error message to understand but best guess is that somewhere in your code it says export default instead of export default insert component name.
In React component :
I am setting
const object = {
name: this.state.Name,
place: this.state.Place
}
callBackend(object).then(validateResult => {
if (validateResult.valid === true) {
this.setState({status: 'saved'});
} else {
this.setState({status: 'error'});
}
}
--------------
// this call goes to service
import axiosInstance from "../Axios";
export const callBackend = (object) =>
axiosInstance.post(`/employee/saveInfo`, { object }).then(res => {
console.log(res);
return res.data;
});
----------------
In java:
#PostMapping(path = "/saveInfo")
public ResponseEntity<List<object>> saveInfo(#RequestBody Object o) {
System.out.println(o.getName);// getting java.lang.NullPointerException
}
Solution is no brackets around object.
export const callBackend = (object) =>
axiosInstance.post(/employee/saveInfo, object).then(res => {
console.log(res);
return res.data;