How to use particular room data on crossdomain server using socket.io? - node.js

I'm using socket io to communicate the cross domain server and also passing the particular data, but i want to use the data on particular room on crossdomain
Here is my code
server side
io.emit('sendData', data);
Cross domain serverside
var socket = io('https://localhost:3000/', { transports: ['websocket'] });
socket.on('sendData', function (data) {
console.log(data);
})
How to solve this? Someone please help to solve this issue

That's not possible to use particular room data on a cross-domain server using socket.io
you only emit the data globally using io.emit(), only solution for compare your emit data with a cross-domain data

Related

Uncaught TypeError: socket.to is not a function

I want to emit some data to a room in socket.io.
According to the socket.io docs,
In one place (https://socket.io/docs/rooms-and-namespaces/#Joining-and-leaving) it is said,
io.to('some room').emit('some event');
And in another place (https://socket.io/docs/emit-cheatsheet/) it is said,
socket.to('some room').emit('some event', "description");
I tried both of these but got the error,
uncaught TypeError: io.to is not a function
and
uncaught TypeError: socket.to is not a function
All other socket.io functions i used worked except for this
I included
<script src="/socket.io/socket.io.js"></script>
in the head tag of the html file.
In the client side js file, i incuded
const socket = io.connect("http://localhost:3000/");
Also, I used socket.emit and it works the way it is supposed to.
Please tell me what is wrong with this..
If this Uncaught TypeError is happening on your client side, that's because io.to and socket.to are only server-side functions, and cannot be used on the client side. In the Client API part of the Socket.IO docs, it doesn't specify io.to and socket.to as valid API functions. Here is the client API docs.
And here is a snippet that you can use to emit to Socket.IO rooms:
Server
//Your code...
io.on("connection", socket => {
//Don't forget to do this!
socket.join("some room");
socket.on("some event", data => {
//Do socket.to if you want to emit to all clients
//except sender
socket.to("some room").emit("some event", data);
//Do io.to if you want to emit to all clients
//including sender
io.to("some room").emit("some event", data);
});
});
Client
//Remember to include socket.io.js file!
const socket = io.connect("http://localhost:3000");
socket.on("some event", data => { /* Whatever you want to do */ });
//To emit "some event"
//This will also emit to all clients in the room because of the way the server
//is set up
socket.emit("some event", "description");
If you need an explanation...
So what this does is, basically, since you can't emit to rooms on the client side (you can only emit to server), the client emits to the server, and the server emits the event to the room you want to emit to.
Hope this solves your problem :)
Step1: In the client-side js file, changes instead of io.connect("http://localhost:3000/") use given below line,
let io = require('socket.io').listen(server.listener);
Step2: You need to create a connection in (Both Client & serverSide) For the Testing purpose you can use check connection Establish or not Both End use can use Socket.io tester Chrome Extension.(https://chrome.google.com/webstore/detail/socketio-tester/cgmimdpepcncnjgclhnhghdooepibakm?hl=en)
step3: when a socket connection is Established in Both ends then you emit and listen to data Easily.
One thing when you listen to the data then sends Acknowledgement using Callback Function. I have Received data Successfully.
E.g.`
socket.on('sendMessage',async (chatdata,ack)=>{
ack(chatdata);
socket.to(receiverSocketId).emit('receiveMessage',chatdata);
});
`
yours, emitting a message is correct no need to change this one. But make sure and please check it again your socket connection is Establish successfully or not. another Shortcut way you can debug a code line by line you can easily resolve this problem.
I Hope using this approach you can resolve the Error, and it is help For a Future.
thanks:)

How to set id of a socket in WebSocket?

I'm using: https://github.com/websockets/ws as websockets.
In socket.io you could give an id to your sockets like:
io.emit('id','myText');
io.on('id',function(data){
//read data
});
In websocket on the server you can read sockets by id.
ws.on('id', function (data) {
};
You can read sockets by id on the client too.
ws.addEventListener('id', function (data) {
};
But I couldn't find how to send a socket with a specific id, I've also checked the code base. Am I missing something or is this impossible? Or are there some hacks that could achieve this?
//I want this:
ws.send('id','myText');
I'll format my comments into an answer since it appears to have explained things for you:
There is no handler for your own message names like this in webSocket:
ws.on('id', function(data) { ... });
Instead, you listen for data with this:
ws.on('message', function(data) { ... });
If you want to send a particular message name, you send that inside the data that is sent. For example, data could be an object that you had data.messageName set to whatever you want for each message.
It appears like you're trying to use a socket.io API with a webSocket. That simply doesn't work. socket.io adds a layer on top of webSocket to add things like message names. If you want to use that type of layer with a plain webSocket, you have to implement it yourself on top of a webSocket (or just use socket.io at both ends).

Need to know something regarding socket.io and redis and nginx

My goal is to build a chat application - similar to whatsapp
To my understanding, socket.io is a real-time communication library written in javascript and it is very simple to use
For example
// Serverside
io.on('connection', function(socket) {
socket.on('chat', function(msg) {
io.emit('chat', msg);
});
});
// ClientSide (Using jquery)
var socket = io();
$('form').submit(function(){
socket.emit('chat', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat', function(msg){
$('#messages').append($('<li>').text(msg));
});
1) do I always need to start an io.on('connection') to use the real-time feature or i could just start using socket.on object instead? for example i have a route
app.post('/postSomething', function(req, res) {
// Do i need to start an io.on or socket.on here?
});
because i want the real-time feature to be listen only on specific route.
2) Redis is a data structure library which handles the pub/sub, why do we need to use pub/sub mechanism?
I read alot of articles but couldn't grasp the concept. Article example http://ejosh.co/de/2015/01/node-js-socket-io-and-redis-intermediate-tutorial-server-side/
for example the code below
// Do i need redis for this, if so why? is it for caching purposes?
// Where does redis fit in this code?
var redis = require("redis");
var client = redis.createClient();
io.on('connection', function(socket) {
socket.on('chat', function(msg) {
io.emit('chat', msg);
});
});
3) Just wondering why I need nginx to scale node.js application? i found this stackoverflow answer:
Strategy to implement a scalable chat server
It says something about load balancing, read that online and couldn't grasp the concept as well.
So far I have only been dealing with node.js , mongoose simple CRUD application, but I'm willing work really hard if you guys could share some of your knowledge and share some useful resources so that I could deepen my knowledge about all of these technologies.
Cheers!
Q. Socket.on without IO.on
io.on("connection" ... )
Is called when you receive a new connection. Socket.on listens to all the emits at the client side. If you want your client to act as a server for some reason then (in short) yes io.on is required
Q. Redis pub/sub vs Socket.IO
Take a look at this SO question/anwer, quoting;
Redis pub/sub is great in case all clients have direct access to redis. If you have multiple node servers, one can push a message to the others.
But if you also have clients in the browser, you need something else to push data from a server to a client, and in this case, socket.io is great.
Now, if you use socket.io with the Redis store, socket.io will use Redis pub/sub under the hood to propagate messages between servers, and servers will propagate messages to clients.
So using socket.io rooms with socket.io configured with the Redis store is probably the simplest for you.
Redis can act like a message queue if it is a requirement. Redis is a datastore support many datatypes.
Q. Why Nginx with Node.js
Node.js can work standalone but nginx is faster to server static content.
Since nginx is a reverse proxy therefore servers are configured with nginx to handle all the static data (serving static files, doing redirects, handling SSL certificates and serving error pages.
) and every other request is sent to node.js
Check this Quora post as well: Should I host a node.js project without nginx?
Quoting:
Nginx can be used to remove some load from the Node.js processes, for example, serving static files, doing redirects, handling SSL certificates and serving error pages.
You can do everything without Nginx but it means You have to code it yourself, so why not use a fast and proven solution for this.

Sending sockets to client side, Error: Converting circular structure to JSON

I'm working in node JS and I'm trying to send an array, with my clients, from the server to every client with a normal emit, but it keeps giving me this error:
data = JSON.stringify(ev);
TypeError: Converting circular structure to JSON
Shortly, this is what I do.
var clients = new Array();
io.sockets.on('connection', function(socket) {
clients.push(socket);
socket.on('loginUser', function(data){
io.sockets.emit("getUsers", clients);
});
I've seen a couple of other people having this problem, but all those answers didn't work out for me.
Looking at the bigger problem, you can't just send an array of sockets to the client side. Sockets are objects which only make sense in their current context/process. If you want to control the sockets from client side, I just instead add some sort of RPC functionality.

Adding data to a socket.io socket object

I am trying to add some custom information to my socket object on connect, so that when I disconnect the socket, I can read that custom information.
IE:
// (Client)
socket.on('connect', function(data){
socket.customInfo = 'customdata';
});
// (server)
socket.on('disconnect', function () {
console.log(socket.customInfo);
});
Since it is JavaScript you can freely add attributes to any object (just as you did). However socket.io does give you a built-in way to do that (so you won't have to worry about naming conflicts):
socket.set('nickname', name, function () {
socket.emit('ready');
});
socket.get('nickname', function (err, name) {
console.log('Chat message by ', name);
});
Note that this is only on one side (either client or server). Obviously you can't share data between client and server without communication (that's what your example suggests).
The socket in your browser and the socket in the server won't share the same properties if you set them.
Basically you have set the data only at the client side (which is in your browsers memory NOT on the server).
For anyone still looking for an answer, there are a couple of things you can do to share data from the client to the server without actually sending a message.
Add a custom property to the auth property in the client socketIo options. This will be available to the server event handlers in socket.handshake.auth.xxxx.
Add a custom header to the transportOptions.polling.extraHeaders property in the client socketIo options. This will ONLY be presented when the socket.io client is connected via polling and not when "upgraded" to websockets (as you can't have custom headers then).
Add a custom query property to the client socketIo options. I don't recommend this since it potentially exposes the data to intermediate proxies.

Resources