I am having trouble tracking down why my emits from my react client app are not getting to a localhost socket server. I am using a forked copy of PuppyJS that I modified to receive client events (https://github.com/BlackConure/puppyjs) via a socket.
I can us the Apic Chrome browser extension and connect to and send/receive messages to the server side just fine via web sockets, but when I try to connect via my client application in React, the connect seems to work, but the emit does nothing.
I have enabled localstorage.DEBUG='*' on a client side and it does not display anything happening with socket.io. I also started chrome with --disable-web-security to eliminate the possibility of a CORS issue; so all indications are that the issue is with my client setup.
Here is the configuration:
- Server:
- Socket on http://localhost:3000/ws
- Nodejs version: 10.3.0
- Client:
- Served via http://localhost:3006
- socket.io-client version 2.1.1
Just to be sure that the socket wasn't trying to re-use the existing (3006) connection, I also tried a forceNew. Still doesn't work.
var socket = io.connect('ws://localhost:3000', {
path: '/ws',
transports: [ 'websocket' ],
forceNew: true
});
console.log(socket);
socket.on('connect', function() {
alert('connect');
});
socket.on('event', function(data) {
alert('event');
console.log(data);
});
socket.on('disconnect', function() {
alert('disconnect');
});
socket.on('error', function(data) {
console.log(data || 'error');
});
socket.on('connect_failed', function(data) {
console.log(data || 'connect_failed');
});
socket.emit('LOGIN', 'Testing 123');
newstate.socket = socket;
return newstate;
Even though on the server side, I get a connect from my client application, it never seems to get to emit.
When I inspect the socket object, io.readyState says opening; so I thought something must be going on with the response from the server. I did a RawCap & Wireshark dump and found that the client received the HTTP 101 Switching Protocols response (same as in Apic); but nothing happens after that.
I traced the emit, and it is throwing the LOGIN into the request buffer (since connected=false), which I am assuming is because it is not in a readyState.
This made no sense, so I started up a simple NodeJS server using Socket.IO as the server, and it all works fine!
Does this mean that Socket.IO and WebSockets are not compatible or did I do something dumb on my part? I thought Socket.io was supposed to be able to handle different protocols. David Walsh's article (https://davidwalsh.name/websocket) states:
Socket.IO simplifies the WebSocket API and unifies the APIs of its fallback transports. Transports include:
- WebSocket
- Flash Socket
- AJAX
- long-polling AJAX
- multipart streaming
- IFrame
- JSONP polling
Am I missing something? If these are not compatible, does that mean we now have to code differently depending on the communication layer?
HTTP 101to get into the ready state and being able to exchange messages. But this requires an understanding of the internals of the socket.io protocol. You could make the socket.io server communicate with the client and inspect that with wireshark (or just in the chrome network tab). I guess there is a lot more happening that you'd expect. - trixn