Socket.io: Changing query parameter issue

Created on 10 Jul 2014  路  25Comments  路  Source: socketio/socket.io

I am hoping I can get some direction on this.

Initializing the io with io(url,opts) works with the query parameter. If that query parameter needs to change you can dot into the sio.io.opts object. However, after it is changed that way, it is not able to be changed again.

Iteration 0 - Works On Initialization


socket = io(options.socket,{query: {_accessToken: 'cow'} });

Server's socket.request._query._accessToken returns 'cow'

Iteration 1 -Works When changed the first time


socket.io.opts.query._accessToken = 'moo';

Server's socket.request._query._accessToken returns 'moo'

Iteration 2 - Doesn't work anymore


socket.io.opts.query._accessToken = 'twomoos';

Server's socket.request._query._accessToken returns 'moo''

Although it seems to change on the client side, the server still returns the value of the access token in Iteration 1.

Doing some digging, I found that the

socket.io.engine.transport.ws

contains the URL for the request, but keeps the _accessToken as the iteration 1 variable.

ws://192.168.1.8/socket.io/?_accessToken=moo&transport=websocket&sid=mY9rC4km7ASypgDTAAAI

I can't change the variable using javascript because it still stays the same. That also seems rather hacky and I'd like to not do that.

I haven't put in an issue request for anything, so I hope this counts as a legitimate one.

Socket.IO v3

Most helpful comment

Any update on this issue ?

All 25 comments

So I found one of the ways to resolve this as a workaround is to create a new io.Manager and pass in the new token (after I do socket.destroy() on the original object as a test)

socket = io(options.socket);

socket.io = new io.Manager(options.socket,{query: {_accessToken: $auth.getToken()} });

This seems to effectively reconnect and change the token each time (or any other query params). I don't know if this is what you are supposed to do since most articles I read suggest changing the opts.query

Hoping to get some insight or see if we can find if its a bug?

I've been providing the query string through the url (instead of through a query property of the options object). And I've been experiencing that it doesn't pick up query changes at all.
Looking through the code it doesn't pass changes properties to a cached manager. (Unless the namespace changed or options like forceNew, or multiplex are used).
https://github.com/Automattic/socket.io-client/blob/master/lib/index.js#L36

I can confirm this by enabling the debug for engine.io* and socket.io*. I see that eventhough I changed the querry string in the url it opens the old url. (Through the socket.io-client:manager opening ... statement)

Also, I don't see a query property used in the code... Are you sure this is supported?
You are using version 1.x and not 0.9 right?
Maybe you can also debug this by enabling the debug statements of socket.io and engine.io.

A bigger issue for me is that I can't work around this with forceNew, without always using it (disabling multiplexing in general). It will pick up query string changes when forceNew is enabled, but when I don't supply this anymore it will fallback to the old & cached manager and it will use the old query string again.
This is partly caused by the fact that a connection made with forceNew or disabling multiplex are not cached.

Actually I now see that it should make a new connection when it's the same namespace since a few days, see the commit below. That would solve my issue. Maybe this is not released yet. I'll check.
https://github.com/Automattic/socket.io-client/commit/7d237cc91fbb34ce484b188cf7d10462c6b34bd9
Also see: https://github.com/Automattic/socket.io/issues/1956

The fix that would solve my situation is not released yet.

I can't believe that this issue exist and is not implemented just from the begining ..

The same problem for me :(

+1

+1

+1

+1

+1

On socket.io 1.4.4, even with forceNew parameters, query modification using "socket.io.opts.query" is not considered on reconnection. This is working with version 0.9 using "socket.socket.options.query".

+1

any update on this issue ? still exist with v1.4.8

+1

+1

+1

+1

Any update on this issue ?

"socket.io-client": "2.1.1"

Ran into this problem myself today and I think I may have found a solution.
I was able to change the query parameter option by updating the mysocket.query object.

The solution as proposed in the client query object documentation did not work for me (mysocket.io.opts.query did not change the query param for the socket)

// On socket creation
const authToken = localStorage.getItem('authToken');
const mysocket = io(`${serverUrl}/${namespaceName}`, {
  transports: ['websocket'],
  query: { authToken },
});

// Somewhere else in my code after I have updated the localStorage
const authToken = localStorage.getItem('authToken');
mysocket.query = { authToken }

// Next time I 're-connected' the socket, the query param was updated correctly and the new authToken was sent

The mysocket object looks as follows:

{
  "io": {},
  "json": {},
  "nsp": "/Test",
  "ids": 0,
  "id": "/Test#randomString",
  "acks": {},
  "receiveBuffer": [],
  "sendBuffer": [],
  "connected": false,
  "disconnected": true,
  "flags": {},
  "query": { "authToken": "Whaterver Your Auth Token Is"}, // <-- I was able to update this directly
  "subs": null,
  "_callbacks": { "$connecting": [null], "$connect": [null], "$action": [null] }
}

Hopefully this helps.

@GStipick Yes, but it is updated only once.
When I try to update it again, it does not work.

This function works for me:

updateAccessToken(accessToken: string) {
    this.socket.close();
    this.socket.io.opts.query = { accessToken }
    this.socket.connect();
}

I am on socket.io-client 2.3.0

Why isn't this fixed after six years? 馃 Is there any way to change the query without calling this.socket.close()?

Why isn't this fixed after six years? 馃

Why dont you fix this? 馃 This is an open source project...

The problem is that the query parameter is used both by the Manager (and the underlying Engine.IO client) and the Socket.

The solution by @GStipick will only work for a Socket in a non-default namespace:

const socket = io('/admin', {
  query: { abc: 'def' },
});

socket.on('reconnect_attempt', () => {
  socket.query = {
    token: 'ghi'
  }
});

For the default namespace, you must update the query option of the Manager (which will be included in the query params of the HTTP requests):

const socket = io({
  query: { abc: 'def' },
});

socket.on('reconnect_attempt', () => {
  socket.io.opts.query = {
    token: 'ghi'
  }
});

This change will only be used upon reconnection to the namespace (hence the reconnect_attempt event).

This inconsistency will be fixed in Socket.IO v3, please see my proposition here: https://github.com/socketio/socket.io/issues/3250#issuecomment-704245631

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adammw picture adammw  路  4Comments

thebinarypenguin picture thebinarypenguin  路  4Comments

doughsay picture doughsay  路  4Comments

shashuec picture shashuec  路  4Comments

varHarrie picture varHarrie  路  3Comments