React-native: RN + socket.io - Failed to set the 'responseType' property on 'XMLHttpRequest'

Created on 16 May 2017  Â·  12Comments  Â·  Source: facebook/react-native

Description

Explain what you did, what you expected to happen, and what actually happens.

Good morning,

I am having an issue combining React Native with socket.io. I do hope I am in the right place here, but considering I am using the same code on React Native and React while only encountering issues in RN, I figured it was worth a shot. It's a bit of an odd issue, and I've tried looking online but I'm having trouble figuring this out. Other people seem to be able to work with socket.io + RN, so I'm a bit stumped.

I am trying to connect to a backend server through socket.io but it seems that as soon as I try to do this, React Native complains to me:
"Failed to set the 'responseType' property on 'XMLHttpRequest': The response type cannot be set after the request has been sent."

I am not actually creating an XMLHttpRequest myself (yet I think with React Native the socket connection might fall back to XMLHttp? I read something about this).

Additionally out of curiosity, if I have a server with socket.io running (I do), could I use React Native's own implementation of sockets to connect to it? Is this compatible?

Here is a stack trace:
Http://imgur.com/a/NKa7V

Reproduction Steps and Sample Code

Here is a snippet of what I am currently using:

/**
* { Dependencies }
*/
    var config = require('./../../../../../package.json').config;
    const PORT = config.backEndExternalPort;
    const BASECONNECTION = config.domain;

    // Vendor functions
        // Socket.IO
        import io from 'socket.io-client';
        //import io from 'socket.io-client/socket.io';
        const socket = io.connect(`${BASECONNECTION}:${PORT}`);

        import { setWhisper, setAnnouncement, connectLobby, updateSessionDetails, startGame, startRound, finishRound, finishGame } from '../../actions/actions'

/**
* { App }
*/

const index = (function() {

    const init = function(view) {

      socket.on('connectLobby', (data) => {
        console.log('Lobby connected!');
        console.log(data);

        view.props.dispatch(connectLobby(data));
      });

Additional Information

  • React Native version: "0.44.0"
  • Platform: Android
  • Development Operating System: Windows
  • Dev tools: Android Dev Studio, everything configured with versions as per the "Getting started" guide for RN.
    ( "socket.io-client": "^2.0.1" )
Locked

Most helpful comment

Try this: const socket = io(${BASECONNECTION}:${PORT}, { transports: ['websocket'] });
not sure how to add code with the es6 backticks, but make sure to re-add those too...

All 12 comments

Could you confirm that you are really running React Native and Socket versions you indicated?

npm list | grep 'socket.io-client@' and npm list | grep 'react-native@' If you don't have grep set the depth to zero or 1 increase until you see the packages

npm list -g --depth=1

Make sure these versions are really installed. Also you can remove any ^ in front of packages and do npm install. Actually I would do this - then delete node_modules and do another
npm install

Also try npm install socket.[email protected] --save // assuming this is latest you want to use.
npm install [email protected] --save
npm install // install everything else

Show us what's in your package.json and tell us if socket client 2.0.1 is latest or why you are using it and if it's really installed along with the right version of react-native. Only then should we dig deeper into this. You would think that npm guarantees install of right versions or would tell you otherwise but this is not the case. It might just grab something from external repo especially if path to local node_modules in your gradle build is not pointing in the right place.

Thank you for getting back to me! As instructed I have reinstalled all my
packages and I can confirm I am indeed using the versions as mentioned.
Issue still occurs.

Here are my deps:
"dependencies": { "es6-symbol": "^3.1.1", "react": "16.0.0-alpha.6", "react-native": "0.44.0", "react-redux": "^5.0.4", "redux": "^3.6.0", "redux-logger": "^3.0.1", "redux-thunk": "^2.2.0", "socket.io-client": "2.0.1" }, "devDependencies": { "babel-jest": "20.0.0", "babel-preset-react-native": "^1.9.1", "jest": "20.0.0", "react-test-renderer": "16.0.0-alpha.6" },

Some extra information, as soon as I import the file that calls to
socket-io, I am seeing these errors in the packager Only in the packager. I
enabled remote debugging and saw in the console only the error message that
I mentioned in my first post. I put console.log calls in that file and in
the remote debugger and it seems to work its way through the file just fine
in the remote debugger, except for that original error message as shown in
first post.

{ [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' } SyntaxError: Unexpected end of input at parse (native) at process._tickCallback (node.js:406:9) { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' } SyntaxError: Unexpected end of input at parse (native) at process._tickCallback (node.js:406:9) Error: write UNKNOWN at exports._errnoException (util.js:856:11) at Socket._writeGeneric (net.js:679:26) at Socket.<anonymous> (net.js:636:12) at Socket.g (events.js:273:16) at emitNone (events.js:85:20) at Socket.emit (events.js:179:7) at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1044:10) { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }

On 16 May 2017 at 11:27, dobrienlzd notifications@github.com wrote:

Could you confirm that you are really running React Native and Socket
versions you indicated?

npm list | grep 'socket.io-client@' and npm list | grep 'react-native@'
If you don't have grep set the depth to zero or 1 increase until you see
the packages

npm list -g --depth=1

Make sure these versions are really installed. Also you can remove any ^
in front of packages and do npm install. Actually I would do this - then
delete node_modules and do another
npm install

Also try npm install socket.[email protected] --save // assuming this is
latest you want to use.
npm install [email protected] --save
npm install // install everything else

Show us what's in your package.json and tell us if socket client 2.0.1 is
latest or why you are using it and if it's really installed along with the
right version of react-native. Only then should we dig deeper into this.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/13991#issuecomment-301726451,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ANPnHVKwiFMCMXC1EUOwADMbm8FCk8XBks5r6WwMgaJpZM4NcDNz
.

React-native isn't complying with the spec here, it is valid to set responseType after the request has been sent.

Try this: const socket = io(${BASECONNECTION}:${PORT}, { transports: ['websocket'] });
not sure how to add code with the es6 backticks, but make sure to re-add those too...

Thank you @Maftalion! That did it. Much appreciated.

Thanks everyone for taking the time and work this out with me. I will close the ticket.

@deanvaessen if I may intervene, I think @Nibbler999 is right here, it seems there is an issue with XMLHttpRequest implementation, it shouldn't throw "The response type cannot be set after the request has been sent" here:

xhr.onreadystatechange = function () {
  if (xhr.readyState === 2) {
    var contentType;
    try {
      contentType = xhr.getResponseHeader('Content-Type');
    } catch (e) {}
    if (contentType === 'application/octet-stream') {
      xhr.responseType = 'arraybuffer'; // <== should not throw
    }
  }
  if (4 !== xhr.readyState) return;
  // ...
};

Using { transports: ['websocket'] } (that is, disabling the xhr-polling transport) may work but it is only hiding the underlying issue.

@darrachequesne Thanks you for the input! That's a fair point, I agree. In that case I will reopen the ticket and let the developers chime in on how to proceed.

any updates on this ?

Hi,

any plans to fix this issue?

+1 for fixing. Without it, socket.io (at least) cannot be used in RN with http-long poll fall back, which is important to have in case someone is running a socket.io-server behind an AWS ELB.

It looks like it'd be as simple as removing this throw: https://github.com/facebook/react-native/blob/9b4a644fec94422c2976f11be0ccf66f2715d9bd/Libraries/Network/XMLHttpRequest.js#L178

But I'd love to understand the reason for that throw, if it's not spec as @Nibbler999 is implying.

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

Hey, I'd like to know what the 'down side' of @Maftalion solution, in which cases it won't work ?

Was this page helpful?
0 / 5 - 0 ratings