I create a server using nowjs. How can I serve clients grouped under an URL.
It's a wague way of putting the question. I ll give an example.
I run my server(with nowjs) in mysite.com which contains many chat rooms.
Users can join one of the chat rooms and start chatting. Real time sync happens - all handled by nowjs.
Now coming to my problem, I'm not able to differentiate between the chat rooms. Whatever chatroom user joins, since I'm using the everyone object, every user gets a message (independent of which chat room he is in).
use a group object.
I solved this issue by using
everyone.now.distributeMessage = function(message,groupname){
group = nowjs.getGroup(groupname);
group.now.receiveMessage(this.now.name, message, groupname);
}
everyone has access to that function, and by passing the groupname, only those who are members of that group get the message.
Related
In my Node.js server, I have an array of client IDs, and I have a socket that I want to send to all connected clients except for the clients I have in that array, so I want to emit to all clients excluding some clients that i have defined by id, is that possible?
Answering my own question after some research.
One thing you could do is to add the clients you want to exclude inside of a Scoket.io room and then emit to everyone except for that room, like shown below:
io.except("room1").emit(/* ... */); // to all clients except the ones in "room1"
Note that this feature was implemented in version socket.io#4.0.0.
here is documentation for it
This is my database structure:
I want new messages to generate a notification.
How do i query this data to ensure the member is part of the conversation and then pass just the child_added of the new message.
This is what i have so far but it will return the entire conversation when a message is added.
const notificationChecker = database.ref("chats")
.orderByChild(`members/${userId}`)
.equalTo(true);
notificationChecker.on('child_changed', snapshot => {
console.log(snapshot.val());
});
Since you're listening on chats, the result of your query will be child nodes chats. There is no way to change that behavior and it is one of the many reasons why experienced Firebasers recommend working with separate top-level lists for each entity type in your app.
It seems like you want the new messages for the current user in all conversations that they are part of. That is a three step process:
Determine the current user
Find what conversations they're part of.
You'll typically do this by having a separate top-level list user-conversations, and then the UID as a key under that, and the conversation IDs as keys (with value true) under that. See https://stackoverflow.com/a/41528908/209103
Find the new messages in each conversation.
The best way to do this is to know what the last message is that the user saw in each conversation. In linear chat apps, you could model this by storing the key of the last chat message the user saw under /user-conversations/$uid/$conversationid, instead of the true we used above.
If that is not possible, you can simply load the newest message for each conversation (conversationRef.orderByKey().limitToLast(1)) and then start listening from there (conversationRef.orderByKey().startAt(keyOfLatestMessage)).
Either way, you will need to do this for each conversation that the user is part of.
I wrote a chat program in Node.js. The server manages a list of rooms in a class called RoomManager with an object this.rooms. Whenever a command is sent to the server from a client, it goes into a router. Most of the commands deal with rooms (sending messages to rooms, joining rooms, creating rooms..). The command message must always have a room ID in it. The server must always try and find the room first:
roomManagerGetRoom(roomName){
return this.rooms[roomName] || null;
}
Since the rooms object will eventually get large, I figured the clients should keep their own references to what rooms they are in. That way, the server could first try and find the room from the client's own list which would be much smaller, 1-4 rooms on average.
However, this creates a cyclical loop
RoomManager requies Room requires ClientManager requires Client requires RoomManager requies Room requires ClientManager requires Client ...
So 1.5 questions:
How much speed would I be gaining by first looking through Client's own list?
If it's significant, how do I avoid the cyclical issue?
I am developing a webapp in which I'd need one client, associated with the admin, to trigger an event (e.g., a new value selected in a dropdown list) which in turns will tell all the other connected clients to change the subscription, possibly using a parameter, i.e., the new selected value.
Something along the lines of
Template.bid.events
"change .roles": (e, tpl) ->
e.preventDefault()
role = tpl.$("select[name='role']").val()
Meteor.subscribe role
Of course this works for the current client only.
One way I thought would be keeping a separate collection that points a the current collection to be used, so the clients can programmatically act on that. It feels cumbersome, thou.
Is there a Meteor-way to achieve this?
Thanks
In meteor, whenever you have a problem that sounds like: "I need to synchronize data across clients", you should use a collection. I realize it seems like overkill just to send one piece of data, but I assure you it's currently the path of least resistance.
There are ways you can expose pseudo-collections which don't actually write to mongo, but for your use case that really sounds like overkill - new Mongo.Collection is the way to go.
You can use streams to setup a simple line of communication between connected clients and the server. It doesn't store data in MongoDB. Just let all connected clients listen to a stream and switch subscriptions when a new message comes in with the subscription name. Make sure only your client associated to your admin can push messages to the stream.
Available package: https://atmospherejs.com/lepozepo/streams
Examples: http://arunoda.github.io/meteor-streams/
I have a node.js/socket.io webapp that is currently working correctly polling an API and populating the html page with the emitted results.
My problem is that multiple people need to use this and I would like to separate their instances so that each person will only receive the results of their query.
Right now, when anyone uses the site it will return results of another user that may be also using the site.
I have tried to get around this using this method:
var clients = {};
io.sockets.on('connection', function(socket){
console.log("this is "+socket.id);
clients.id = socket.id;
})
io.sockets.socket(clients.id).emit('progress',{info:listing});
Of course this gets replaced with each new user that logs into the site so then everything that was emitted to the original user is now being emitted to the new user.
What I want to know is if there is any built-in function to get around this or if I should proceed with another persistent store.
Any help would be greatly appreciated.
Edit
By storing the socket object in the express.sessionStore instead of just in the program.
io.sockets.on(function(socket){
request.sessionStore.socket = socket;
})
The above code now works and only emits to the event originator.
This looks like it's been answered in another thread. The idea is to create an array of clients, and associated it to some type of client/user identification, like an ID or name.
Sending a message to a client via its socket.id