I need to implement a reconnect handler which first request a token over ajax from another server which is used as authentication on the websocket server.
Step 1: connect to http://test.com/{my_temp_token}
Step 2: on disconnect get new token
Step 3: connect to http://test.com/{my_new_temp_token}
Does socket.io automatically reconnect on disconnect? When yes how to implement an own reconnect handler, when no best way to handle an auto reconnect with an ajax loaded authentication token.
Socket io has a list of event listeners that it supports out of the box. If you want to do something custom on reconnect then you would just do...
this.socket.on('reconnect', e => {
// Socket has successfully reconnected
console.log(`It took ${e} tries to reconnect`);
// Do something custom like requesting a new token here...
});
Hope that helps!
Related
I'm using cometd to listen to platform events generated in Salesforce. My cometd client configuration code looks like
this.client.configure({
url: `${this.org.instance_url}/cometd/46.0`,
requestHeaders: {
Authorization: `Bearer ${salesforceToken}`
},
appendMessageTypeToURL: false
});
where the salesforceToken is obtained using the refresh token. This all works fine for a while but if there are no events for a considerable period of time (anecdotally anywhere between 6-24 hours), then my client seems to expire and no events are received. If I refresh the token and restart my listener, things start working again.
Is there a way to keep the listener active other than writing some sort of timer to restart the process every few hours after inactivity ?
You do not have to refresh the token again
Whenever there is no activity on the channel, the server closes the connection after a specific time.
In that time client receives a 403 (Unknown client) status code, and the client has to handshake again withing 110 seconds.
By default, CometD tries to reconnect without any user interaction and If the client doesn't reconnect within the expected time, the server removes the client's CometD session.
Once the connection gets reconnect, all the channel subscriptions will be removed by ComedD, and we have to subscribe to the channel again in order to receive events.
In order to do so, we have to make use of meta/Handshake callback to resubscribe to the channel again.
see https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/using_streaming_api_client_connection.htm, paragraph "After Invalid Authentication"
"Streaming API regularly validates the OAuth token or session ID while the client is connected. If client authentication is not valid, the client is notified with the 401::Authentication invalid error and an advice field containing reconnect=none. After receiving the error notification in the channel listener, the client must reauthenticate and reconnect to receive new events."
(X) First Scenario
We have a web application and we are using socket.io as middleware. There is an angular end and there are API from .net. and it is a chat application, when a user sends a message it calls for the socket server and from socket server, we call to the API and we send the message to the particular socket. but when we send the message to the client the client event gets called multiple times(not every time but sometimes) from the angular end but the message, we have only sent once from the server(we set a logger to confirm this from server end). We have Azure Linux server. We are pooling socket ids from user ids as rooms. Though we removed rooms and added a manual array to pool sockets ids from user ids issue still exists. Working fine on android and ios devices.
****Second scenario
when we disconnect internet connection and reconnect the connection gets to connect to the server and we send a message after that it does send the message to other ends, but if we are sending messages from other end, messages are not coming to this end, from loggers in a server it shows that messages are sent. to the particular socket ids.
Setup
socket.io version: V2.0.3
node 6.11.4
I write a Google Chrome Extension that uses Socket.io capabilities. More precisely, it's an AngularJS app with angular-socket.io on board.
I allow users to set up socket.io server address and port in the options page. Everything works fine until a user wants to change the address because I don't know how to reset the Socket.io connection. Ideally, I would like to close previous connection and reconnect with new connection without restarting the app (remember, it's an Chrome Extension, I cannot restart it by itself).
So my question is: How to reset the Socket.io client connection and reconnect with new DSN?
PS. I'm using socket.io-client#1.3.6
You are using angular-socket.io, so you inject socket.io (with a given config) as a service into your angular app. Assuming your service is called socketIOService you can do following:
Disconnect on client-side with socketIOService.disconnect();
Reconnect with socketIOService.connect(SERVER_IP, {'force new connection': true});
EDIT:
I've been doing some additional testing, and this appears to only happen when I'm running multiple instances of the web role hosting the SignalR hub (I'm using a azure service bus backplane). When I'm running a single instance of the hub, I see all messages come through to the client. When I'm running multiple instances, I get these symptoms:
Logging from server indicates that all messages were sent
Logging from client indicates that only some messages were received
Looking at server traffic with wireshark while remoted into the cloud service on azure captures only the messages that the client receives
My suspicion is that the client holds a connection to a single instance of the web role and that when messages happen to originate from the web role to which the client isn't connected, the client can't receive it even when it is broadcast to the correct SignalR connection.
Anyone else having a problem with missing messages when running multiple instances of a SignalR hub hosted in a web site? Is there a way around this problem?
I've got an asynchronous process started via an API call from a javascript client that finishes in one or more messages sent via our SignalR hub back to that client. It appears that not all messages sent from the SignalR hub are received by the javascript client. Below is the flow along with logging messages that I receive:
The client connects to our SignalR hub then immediately calls a subscribe method that associates the current connection id with our internal user identifier:
Websocket opened
Now monitoring keep alive with a warning timeout of 13333.333333333332 and a connection lost timeout of 20000.
Triggering client hub event 'subscribed' on hub 'EventHub'
Client subscribed to event hub: 5539368b-5f82-48bd-8ed9-2c5bed3caefa [this is the indicator that the back end associated the given connection id with the user id]
I start the back end process that should result in two messages being sent back to this client. Logging from within the SignalR hub indicates that two messages were being sent (message lists all connections associated with the given internal user id--I've got old connections in our cache I haven't cleaned out):
event hub broadcasting control action updated to user 124 for control action 120 on connections 5aaea44a-7810-45b5-8119-3ff1fe613d63, 4be9ca16-1e31-42bf-91db-798b757a381c, 5f9f9962-4f8b-4712-929e-c943e28ca91f, de7135ba-4e16-4e9e-9c38-e8f78ed59636, 82e900d1-005e-4bff-95d0-3737632b4671, 0cc273f9-04aa-4570-8cd7-993876219e52, 2b6db0f7-ab0c-41d3-beb5-3b312107a923, 5539368b-5f82-48bd-8ed9-2c5bed3caefa [note connection id from above is included in list]
event hub broadcasting control action updated to user 124 for control action 128 on connections 5aaea44a-7810-45b5-8119-3ff1fe613d63, 4be9ca16-1e31-42bf-91db-798b757a381c, 5f9f9962-4f8b-4712-929e-c943e28ca91f, de7135ba-4e16-4e9e-9c38-e8f78ed59636, 82e900d1-005e-4bff-95d0-3737632b4671, 0cc273f9-04aa-4570-8cd7-993876219e52, 2b6db0f7-ab0c-41d3-beb5-3b312107a923, 5539368b-5f82-48bd-8ed9-2c5bed3caefa [note connection id from above is included in list]
On the client, I'm logging when the method is invoked as a result of a message being sent, and I see:
received controlActionUpdated message from event hub with model: controlActionId 120
Sometimes the client gets all the messages sent from the hub, but more often, it's missing one or two. Relevant code snippets are below:
CLIENT:
We use a generalized eventing service in angularjs. Consumer of events connects and subscribes to a list of events as follows:
eventing.initialize(['controlActionUpdated', 'subscribed']);
The service looks like this:
var cn;
var hubProxy;
var eventsToHandle = [];
var initialize = function(events){
for(var index = 0; index < events.length; index++){
if(eventsToHandle.indexOf(events[index]) == -1){
eventsToHandle.push(events[index]);
}
}
connect();
}
//call this to connect to the eventing hub and set up client-side receiving methods
var connect = function(){
cn = $.hubConnection('https://events.xxx.com/');
cn.logging = true;
hubProxy = cn.createHubProxy('eventHub');
//subscribe to all events currently indicated to be handled
for(var index = 0; index < eventsToHandle.length; index++){
listen(eventsToHandle[index]);
}
hubProxy.on('subscribed', function (model) {
console.log('Client subscribed to event hub: ' + model);
});
cn.qs = { "optiAuthToken" : authentication.getAuthToken() };
cn.start().done(function(){
//subscribe to events for this specific user
hubProxy.invoke('subscribe');
$rootScope.$broadcast('connectedToHub');
});
}
var listen = function(eventName){
hubProxy.on(eventName, function(model){
$rootScope.$broadcast(eventName, model);
});
}
The receiving method to the $rootScope.$broadcast(eventName, model); call above is:
$scope.$on('controlActionUpdated', function (event, model) {
console.log('received controlActionUpdated message from event hub with model: controlActionId ' + model.controlActionId);
[further code omitted]
SERVER:
This method calls our cache to get the list of connections for the executingUserID. If it finds at least one, it sends a message to that list of connections.
public async Task MyControlActionUpdated(ControlActionEventModel model, int executingUserID)
{
EventingConnectionDetails[] currentConnections = await cache.GetCurrentEventHubConnections(executingUserID);
if (currentConnections.Length > 0)
{
Trace.TraceInformation("event hub broadcasting control action updated to user {0} for control action {1} on connections {2}",
executingUserID, model.controlActionId, string.Join(", ", currentConnections.Select(c => c.ConnectionID).Distinct()));
Clients.Clients(currentConnections.Select(c => c.ConnectionID).Distinct().ToList()).controlActionUpdated(model);
}
else
{
Trace.TraceError("attempt to broadcast control action updated to user {0} for control action {1} failed due to no connections",
executingUserID, model.controlActionId);
}
}
I've looked around for other people complaining of the client missing messages from the server but haven't found anything. Does anyone have any ideas why messages logged as sent from the server are not logged as received on the client?
I'm using SignalR 2.0 hosted in a web role in Azure with a service bus backplane. Client is AngularJS version 1.2.14.
The problem was that the service bus backplane was not actually working due to an incorrect configuration on my part (I was calling UseServiceBus on my dependency resolver first then setting the dependency resolver to my unity resolver for DI).
Note to self: check traffic through service bus topic first before trying to dig deeper. :)
I am writing an apache module and I am wondering how to handle the case where my ap_rwrite tries to write something back to the client and the client does not respond to it.
Does the call to ap_rwrite block until that happens?
Can I set a timeout on that? If so, what is it called?
Thanks!
The client does not respond to server again. HTTP is a request-response protocol, the client send a request to the server and server sends a response to client. Client should not respond to server.
If you mean how to know if the client receives the response maybe you can alter the default timeout, but if the socket is closed or other network error, the function 'ap_rwrite' will notice you with an error.