I have already tried all possible trouble shooting for this. The problem is occuring with a single event handler. the messsage is received from serverside. This i confirmed in the network tab, but the event handler is not invoked and no error is thrown.
objConnection.on("FileTransferAccepted", (res) => {
setTransferStatus(true);
});
This is received in the browser
I have also confirmed that the event handler is attached
Im stuck. cant figure out whats wrong with just this handler. tried renaming the handler still no change.
So I finally found the problem.
I created a connection object in one page and forgot to clean up and stop the connection before navigating to another page. Here I created another connection object and updated the connection id in the db so that im reachable. But even after the component is unmounted. the earlier connection was not destroyed. And the message was received it but that object had no event handler to handle this event. All I did was close previous connection on unmount and everything started working fine.
Summary:
Solution 1: In case you have created multiple connections in different pages or components. destroy these connections by calling the "stop()" method on unmount. Also dont forget to update your new connection id in db.
Solution 2: dont create multiple connections for dfferent pages, use the same object throughout the app.
Related
I'm using a simple chat-client for my react-native chat app which uses WebSocket.
Whenever there's an error on the server side and the chat shuts down, causing an error event on my app, sets the readyState to CLOSED meaning I need to restart and try to re-connect.
I have a list of listeners when the socket connects such as: 'chatMessage', 'error', 'userDisconnected', 'userConnected'.
But the problem is, whenever I recreate the client by doing:
initWebSocket() {
this._chatClient = null;
this._chatClient = new ChatClient({
url: `${Constants.chatUrl}:${Constants.chatPort}`,
log: false
});
}
To then call a connect() afterwards, I create a duplicated event listeners of all of them. So when I send/receive a message, it shows twice as if it was indeed sent twice. This is a look & feel thing, because on the server, it only shows the message was sent once. If I go back to the message list screen and then get inside the same chat, it will update and show only 1 message, not 2. So this is 100% a duplicated event listener being called.
How can I solve this specific issue?
User logs into application and it starts a connection and registers a handler to restart SignalR connection if it is lost like this
connection.onclose(this.restartConnection);
I've looked through HubConnection.ts and I did not find any option to remove onclose handler. It cannot be replaced by an empty method because it stores all registered methods. Then there is only option to remove custom handlers through
connection.off('methodName');
When a user logs out the application stops SignalR connection at it inevitably fires the onclose handler which ends up with an error for me. I want to unregister the handler so the connection will not try to restart itself after the application deliberately stopped it.
I thought of using a flag if it should or should not try to restart the connection but that does not seem right to me. Is there a proper solution to this?
On the latest version of the SignalR client (which still doesn't seem to have a documented way to do this) you can just set the onclose callbacks array to empty yourself: connection._closedCallbacks = [].
I'm calling on a client, one-to-one, multiple times during a session and the streamCreated event gets called on the host. When I hang up, I unsubscribe and the client unpublishes. However, when I call on the client again, the streamCreated event gets called twice on the host's side. I call on the client 3, 4, 5, etc. more times and the streamCreated event fires the same number of times as I have called on the client. For example on the 7th time I call the client, streamCreated gets called 7 times! It seems like I'm not really destroying the streams although streamDestroyed gets called.
On the client side, I was desperate enough to try and unpublish with:
clientSession.unpublish(clientPublisher, handleError);
clientPublisher.stream.destroy();
clientPublisher.destroy();
clientPublisher = null;
On the host side, I've also tried to make sure the subscriber was destroyed:
clientSession.unsubscribe(clientSubscriber);
clientSubscriber.destroy();
clientSubscriber = null;
The problem with this is when I open a video monitor with multiple clients and have each client publish without audio. However, I can still hear the client I called on... like their original stream(s) still exists. What am I doing wrong?
Every time I called on the person, I was using:
clientSession.on('streamCreated', function (event) {
clientSubscriber = clientSession.subscribe(event.stream, vid, {
...
So, each time I called on a client, it created a new event handler. To correct the issue, I added the following code when I disconnected from the client.
clientSession.unsubscribe(clientSubscriber);
clientSession.off();
That killed the event handler and everything works properly now.
Is it possible that the onerror callback can be called where onclose will not be called immediately after? In other words, is it possible to get a WebSocket error which does not coincide with the connection then being closed?
If it is possible, I would like to test this case. I have a mocked backend which uses node.js and express-ws. What can I do in the backend to trigger the onerror event callback in the front end.
The error event will only ever be fired prior to then also firing the close event, at least by implementations that properly implement the specification, i.e. you will get error and close as a pair, or just close by itself.
The process for closing a websocket consists of 3 steps, the second of which optionally fires the error event if needed:
If the user agent was required to fail the WebSocket connection, or if the the WebSocket connection was closed after being flagged as full, fire a simple event named error at the WebSocket object. [WSP]
Before the third step then calls close:
Fire an event named close at the WebSocket object, using CloseEvent,...
And because both of these steps are one after the other inside the same queued task, your event handlers should be invoked one after the other, with no other events or tasks taking place in between them.
To limit the cache on the client side we thought we can turn the subscription to a specific Collection on and off by putting the Meteor.subscribe of that Collection in Meteor.render as suggested by the Meteor document - "In addition, calling Meteor.subscribe in a reactive context sets up a subscription which is automatically stopped when the context is invalidated."
However we keep getting the "Uncaught TypeError: Converting circular structure to JSON" error.
The flow of the program is the following:
Appliances = new Meteor.Collection 'appliances'
Alerts = new Meteor.Collection 'alerts'
On the client side
under Meteor.startup subscribes to collection 'appliances'
Meteor.subscribe ('appliances')
Use Appliances.find{}.observe to monitor changes
When a new Appliances item is detected, use Meteor.render to re-actively subscribe to alerts and list all alerts of the item
Meteor.render(function() {Meteor.subscribe(Alerts); .....}
Any idea what I did wrong? Suggestions?
I have no Idea where your Error message comes from. But You can archive the "only when necessary" subscription easily using Deps.autorun() and a Session variable:
anywhere on the client:
Deps.autorun(function () {
if (!Session.get('isViewingAlerts')) Meteor.subscribe('alerts');
});
If you now useSession.set('isViewingAlerts',false), the code in the autorun function is invalidated and gets re-executed.
Even further you could subscribe to a subset of alerts, by adding a parameter to the publish function 'alerts'.
EDIT:
I recently had the Problem, that a Template wasn't reactive when using dynamic subscriptions. As the subscription wasn't loaded on redraw. To solve the Problem we used a callback for Metor.subcribe that changes a Session variable to make the rendering of that Template dependent on the subscription to be ready and thereby gaining reactivity.
-best,
Jan