connect 2 websockets ws and socket.io - node.js

I'm getting data from a web page with websocket but I need to deploy it with socketIO to client. In my server.js client connects with socketio well but after that data(line1 line2) can't comes properly, always I need to restart server 2-3 times.Then it comes.
Here is my declerations
var server = require('http').Server(app);
var io = require('socket.io')(server);
const WebSocket = require('ws')
const wss = new WebSocket('gettingDataAdress');
io.on('connection', function (socket) {
console.log("client connected");
wss.on('open', () => {
console.log("send processing");
//line1
})
wss.on('message', () => {
console.log("getting message processing");
//line2
})
After restarting my server.js 2-3 times it can comes to line1 and line2 , it can't directly.However whenever I comment the socketio Part(I mean only websocket working) it works perfect.How can I do that ? Thank you

You are using two different websockets ws and socket.io. Use only one to connect to the client and subscribe to the coming messages
Only Socket.io
io.on('connection', function (socket) {
console.log("client connected");
socket.on('open', () => {
console.log("send processing");
//line1
})
socket.on('message', () => {
console.log("getting message processing");
//line2
})
Only ws
const WebSocket = require('ws');
const ws = new WebSocket('url');
ws.on('open', () => {
//do processing
});
ws.on('message', () => {
//do processing
});

wanted to write a comment but had no reputation to write, so decide write on here. sorry!
If you want to subscribe, rather use socket.io-client. However, socket-io itself is not a proper library to subscribe wss.
https://github.com/socketio/socket.io-client/issues/1208
actually, Socket.IO is not a WebSocket implementation, it has its own protocol which may use a WebSocket connection to transmit data
-darrachequesne-(most contributor of socket-io client library)
so If you get data from wss page, then use ws library and spread it by socket-io. I believe that what you are doing is pretty fine. might need to fix a bit though.
Connecting to GDAX websocket api using socket.io with webpack
there is similar question to get data from ws.

Related

how to know the client being disconnected from the server when using node.js websocket library ws

I am working the web socket with node.js, the code works in half that it can create connection and receive messages,
var { WebSocketServer, WebSocket } = require('ws')
const ws_server = new WebSocketServer({ port: 8080 });
ws_server.on('connection', (ws) => {
ws.on("message", function(msg,isBinary) {
console.log('on message',msg.toString());
})
// something wrong, client is not defined
ws.on('close', (client) => console.log('Client has disconnected!'),client);
});
however when the client closes the connection, I want to know what client is disconnected.
ws.on('close', (client) => console.log('Client has disconnected!'),client);
this code above gives me an error that client is not defined, so my question is how to know the client information - client id when the client is disconnected from the server.
ws client, which you have in connection callback is Object to which you can add any property you want and it is kept all the time the connection is alive, and also on close.
So add any property that will help you identify your client and use it in the client's on close callback.
const wss = new WebSocketServer({port: 8080})
wss.on('connection', (ws) =>
{ ws.user = CLIENT_NAME;
console.log('CLIENT CONNECTION ESTABLISHED', ws.user);
ws.on('close', (code, data) => {
console.log('CLIENT DISCONNECTED: ', ws.user))
}
}
)
Through the time you will maybe need authenticate the connected client, so follow these instructions. They will help you better identify the incoming client connection.

why socket connected twice in nodejs server with nextjs as the front end?

I hope to get some answers here as i have been trying to debug for few days now.
The expected behaviour:
socket in server connected once when user is in my website.
The actual behaviour:
socket in server connected twice when user is in my website.
I am using Next.js as the front end and node server as backend.
_app.js
const MyApp = () => {
useEffect(() => {
socket.once('connect', () => {
console.log('Connected');
});
return () => {
socket.disconnect();
};
}, []);}
server.js
let connections = [];
module.exports = function (io) {
io.on('connection', async (socket) => {
console.log(socket.id + ' connected', '\n');})}
after hours of research, i finally found the answer!
How To Implement React hook Socketio in Next.js
I followed the top answer and it worked! because nextjs render once in its server and its client.

No response from Socket.io server when client is making a connection

I have been fighting with setting this up for longer than I would like to admit.
At first, I was having CORS issues, after following what the socket.io documentation / other stack overflow threads I was getting hit with, GET / POST 400 errors.
Finally after that, I noticed a few threads mention to pass in {transports: ['websocket']} on the server and in the client.
Once I did that, I stopped getting error messages, however, I am still not able to make a connection from my client to my socket.io server. I am hoping I can get some guidance.
I am running Socket.io 3.0 and express 4+
Here is what my server / client looks like at the moment..
SERVER (As an express router)
const express = require('express');
const socketIO = require("socket.io");
const http = require('http');
let app = express();
let router = express.Router();
let server = http.createServer(app);
// The event will be called when a client is connected.
let io = socketIO(server, {transports: ['websocket']})
io.on("connection", socket => {
console.log("connection")
socket.emit("hello", { data: "more data" })
socket.on("disconnect", () => {
console.log("user left")
})
})
server.listen(8081, () => console.log('Socket.io listening on *:8081'));
module.exports = router;
Client (React)
// Socket.IO
import io from 'socket.io-client';
const socket_io = io('localhost:8081', {transports: ['websocket']})
// Socket.io UseEffect
useEffect( () => {
const initSocket = () => {
console.log(socket_io)
socket_io.on("hello", data => {
setSocket(data);
console.log(data);
});
// CLEAN UP THE EFFECT
return () => socket_io.disconnect();
}
initSocket()
},[])
Here is what my Console currently looks like when I log out the socket connection:
So, as embarrassing as this is, the breaking change was that the socket.io-client module in the React client application wasn't 3.0 like the one on the server. Therefore they weren't able to handshake.
My advice, is if you have the CORS rule added or the transport: websocket added, make sure you look at your package.json file in your server / client apps to make sure that the socket.io package version matches.

Multiple socket.io instances at different paths

I'm making a REST API that works with routes and actions like /api/route/action. But I want to add WebSocket functionalities. So I want WebSockets to also be addressable by url.
I have this code:
const socketio = require('socket.io');
//server is a http.createServer()
module.exports = server => {
const io = socketio(server, { route: '/socketapi/test' );
io.on('connection', s => {
s.on('a', () => s.emit('b'));
s.emit('message', 'You connected to /test.');
});
const io2 = socketio(server, { route: '/socketapi/something_else' });
io2.on('connection', s => {
s.on('z', () => s.emit('y'));
s.emit('message', 'Hi');
});
};
The reason why I want to split them is so I don't have to keep track of event names I've already used, and so I can separate the logic in the connection event.
But it seems this is not possible. If I have two socket.io instances running I can't connect to either.
Is this possible or will I have to use some tricks and perhaps an event that the client can send to let me know what it wants to subscribe to?
You can use a built in feature of socket.io called namespaces to achieve this behaviour.
Here is a basic example:
Server side:
const nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected');
});
nsp.emit('hi', 'everyone!');
Client side:
const socket = io('/my-namespace');
Now the client can emit and receive messages which are specific to a namespace. With the use of namespaces your problem of name conflicts of the events, will be solved.

How does one properly shutdown socket.io / websocket-client?

I'm trying to create a test using LearnBoost's socket.io and the node-websocket-client. Communication between the client and server work great. After all communication is done, I close both the client and the server. Yet the program hangs, waiting on some unknown callback. Two questions:
What is the following program waiting for?
Is there a tool for diagnosing outstanding callbacks in node programs?
var connect = require('connect'),
io = require('socket.io'),
WebSocket = require('websocket-client').WebSocket;
var port = 7111;
var server = connect.createServer();
var socket = io.listen(server);
socket.on('connection', function(client) {
client.send('Welcome!');
client.on('message', function(message) {
console.log(message);
});
client.on('disconnect', function() {
console.log('closing');
server.close();
});
});
server.listen(port, function() {
var ws = new WebSocket('ws://localhost:' + port + '/socket.io/websocket');
ws.onmessage = function(message) {
console.log(message.data);
};
setTimeout(function() {
ws.send('~m~3~m~Yo!');
ws.close();
}, 10);
});
EDIT: changed the variable name of the WebSocket to ws to avoid confusion
var socket = io.listen(server);
You've created a socket on a port. You've never closed it.
socket.server.close() closes your (socket.io) socket.
When in doubt read the socket.io github examples
socket.server === server It's the server you pass in, in the liste statement so it's closed. I'm not sure what it's waiting for.
Below a way to shutdown all the connections and be able to run multiple expresso tests (using socket.io and socket.io-client).
The solution is tricky and buggy but works on 0.8.5. The main problem is regarding the library to use websockets (node-websocket-client).
Currently, on socket.io, the OS contributors have patched the websocket client. So, we must do the same on our socket.io-client npm package to be able to use finishClose method on the socket client side. Socket.io-client uses the websocket library as npm package, so you must find the file (websocket.js) and substitute it with the same on socket.io.
Afterwards, you could use finishClose method to ensure the connections are closed and with some custom server/client socket settings, the tests will run correctly.
var io = require("socket.io").listen(port);
io.set('close timeout', .2);
io.set('client store expiration', .2);
var client = require("socket.io-client").connect( "http://localhost", { port: port , 'reconnect': false, 'force new connection': true});
client.on('connect', function() {
client.disconnect();
});
client.on('disconnect', function() {
client.socket.transport.websocket.finishClose();
io.server.close();
});
io.server.on('close', function() {
setTimeout( function() {
done();
}, 500);
});
Hope, somebody can help.
The program is waiting because socket.io (server) is still listening for incoming connections. I don't know of any way to stop listening.

Resources