Meteor send to active users - javascript

I starting with writing a meteorjs webpage. I started with the leaderboard example. This works great. I added some new functions. I added a jquery notification script. (Noty http://ned.im/noty/ )
When I give a person five points a activate the Noty plugin by using this code
var n = noty({text: txt,timeout: 2000});
......
Template.leaderboard.events({
'click input.inc': function () {
Players.update(Session.get("selected_player"), {$inc: {score: 5}});
notje("Er heeft iemand een score gegeven");
Method.call("callHouse");
},
The notification will only displayed to my browser and not to other users. How can i use a notification to all active users.
Users -> Server -> All users
I hope you can help me with this issue

You would have to create a notifications collection (client & server):
notifications = new Meteor.Collection("notifications");
Then insert your message in there and display it using an observe handle. Make sure you add something which is user specific so that you can use a smaller subset of users. And also identify when its used and mark them as ready so they're no longer published and the user doesn't keep receiving them.
Then you could do something like this on your client side:
Meteor.startup(function() {
notifications.find().observe({
added: function(doc) {
//Message can be contained in doc.txt
//Not sure if this bit is right, but basically trigger the notification:
n = noty({text: doc.txt,timeout: 2000});
}
});
});
Hopefully this gives you a bit of a rough idea on how to do it.

Related

Firebase push() method shuffle the list data

Have created a chat application and we use firebase for realtime communication.
Sometimes i noticed that push() method shuffle the list data. We can see in the below image :
If we see in above image i am just trying to communicate with someone i said hello in reply user said hey, again i said i need some help then user said That's what I'm here for. What can I assist you with? in the reply but if we see in the image users reply is appearing first.
It happens intermittently that's why i didn't figure out this problem. So please someone help me out what shall i doing wrong.
var pushMessageToFB = function(){
var chatMsgRef = db.child("chatMessages").child("gr1").child("ch_usr1_usr2");
var message = {
type: "chat",
content: data.messageText,
timestamp: Date.now(),
by: user.id
};
chatMsgRef.push(message, function(err){
if (err){
console.log('error occurred while pushing message to fb : err ' + JSON.stringify(err));
}
});};
var loadChatMessages = function(){
var chatMsgRef = db.child('chatMessages').child("gr1").child("ch_usr1_usr2");
$scope.chatMessages = chatMsgRef.orderByKey().limitToLast(50);
};
Don't use Date for remote data. It will be slightly offset on every machine. Use ServerValue.TIMESTAMP which Firebase will convert to the server's Unix epoch time when the data is written. This ensures consistency of order across clients.
You didn't provide any code for how you're reading or displaying the chat messages, but since you're trying to show them in chronological order I assume your query uses orderBy("timestamp"). If you use ServerValue.TIMESTAMP when you write the message it will be guaranteed to sort in the order that it was written to the database.

Meteor - sending a message to all clients

I am building an application using Meteor.js with flashMessage to display informative messages for the user. Currently the message is tied to click events of individual users, but I want to display that message for all users.
Is there a way of using Meteor and flashMessages to accomplish this? Or another package should be used?
Cheers.
There are probably multiple ways, but here is one, using a collection of messages:
Common:
Messages = new Meteor.Collection('messages');
Client:
if (Meteor.isClient()) {
Meteor.subscribe('messages');
var msgs = Messages.find();
msgs.observeChanges({
added: function(id, obj) {
FlashMessages.sendInfo(obj.text);
}
});
}
Server:
if (Meteor.isServer()) {
Meteor.publish('messages', function() {
return Messages.find();
});
}
And then just insert messages like {text: "my text"} into the Messages collection and they should be displayed on all clients.
PS: You may want to remove the inserted messages again after a while, or else any newly arriving client will be shown all past messages. Alternatively you could just subscribe to recent messages.

Can you list users in Meteor without a login system?

For example, if I did a chatroom where all you ahve to do is enter a username (so you don't log in), can I still somehow list out all the people in that chatroom? How can I do this?
Instead of using the normal Meteor.users collection, it would probably be easiest to create your own collection for such simple authentication.
If you wanted to make it really simple (most likely, as long as you didn't care if 2 people have the same name), just store the name as a property of a chat room message document.
Edit - answer to comment:
To detect when a user disconnects, you can add an event handler in your publish function like this:
Meteor.publish('some_collection', function(){
var connectionId = this.connection ? this.connection.id : 'server';
this._session.socket.on("close", Meteor.bindEnvironment(function(){
// deal with connectionId closing
}));
});
You can do that.
Simply publish all users and every coming client should subscribe.
server:
Meteor.publish('allUsers', function(){
return Meteor.users.find({},{fields:{profile:1}});
})
client :
Meteor.startup(function(){
Meteor.subscribe('allUsers');
})
Template.listOfUsers.users = function(){
return Meteor.users.find();
}
This is very basic example, which should be adjusted to your needs.

Restrict number of users in a session in vline

Can I restrict the number of users in a session? Is there any option in vline.session? Please guide if this can be done by writing custom javascript.
EDIT:
Referring to https://vline.com/developer/docs/vline.js/vline.MediaSession#examples, a two party call controller is explained. I want to ask is there any way to restrict number of users in a session? There is no such option present in session's docs. Is it supported as a part of the API?
If this can be done using custom javascript, how?
As a part of my effort, I have tried to implement vline-django examples, but could not find a section in documentation that addresses this issue.
EDIT 2: The code that is working for me.
var vlineClient = (function(){
var client, session,
authToken = {{ user|vline_auth_token|safe }},
serviceId = {% vline_service_id %},
profile = {{ user|vline_user_profile|safe }};
// Create vLine client
window.vlineClient = client = vline.Client.create({"serviceId": serviceId, "ui": true});
// Add login event handler
client.on('login', onLogin);
// Do login
client.login(serviceId, profile, authToken);
function onLogin(event) {
session = event.target;
// Find and init call buttons
var callButtons = document.getElementsByClassName('callbutton');
for (var i=0; i < callButtons.length; ++i) {
initCallButton(callButtons[i]);
}
}
// add event handlers for call button
function initCallButton(button) {
var userId = button.getAttribute('data-userid');
// fetch person object associated with username
session.getPerson(userId).done(function(person) {
// update button state with presence
function onPresenceChange() {
button.setAttribute('data-presence', person.getPresenceState());
}
// set current presence
onPresenceChange();
// handle presence changes
person.on('change:presenceState', onPresenceChange);
// start a call when button is clicked
button.addEventListener('click', function() {
person.startMedia();
});
});
}
return client;
})();
How do I move ahead?
Reference: https://vline.com/developer/docs/vline.js/
if i understand correctly the OP is trying to make a multi-user chat room - this is also what i wanted to do with vline and because i wanted a/v chat as well the number of participants should obviously be capped - it appears that the term 'session' is causing the confusion here so i will refrain from using it
i worked around this by creating a fixed number of users in a db and handling authentication
myself before actually associating a visitor with one of the prepared users - so some javascript logs in each visitor as one of those existing 'anonymous' users and sets only a logged_in? flag in the db so that the next visitor will log in as the next vacant user slot and when all slots are occupied the visitor gets a "chat room full - try again later" response
probably not the most elegant solution - for example the visitor chosen usernames are stored client-side and must be re-assigned to one of the user-definable vline session vars so it can be passed along with each message and the logged_in? db flag needs to be reset when the user exits
note that this was almost a year ago so im a bit foggy on exactly what i did but my app (rails) in up on github if youre interested to fork it - also i should add that although this sort of thing wasnt strictly supported by the vline API at the time there were at least some hints that some analogous feature was being prepared for so there may be some API support for this now - i did notice since then that they have released a "chat room demo" app on github and i would expect that their implementation is more concise than mine so you may want to look at that first - my app tho does have a mostly complete UI with gravatars and collaboration is welcomed

Removing someone from a user hash on navigating away from a page / page close

I'm building a Node.js / Socket.io project.
I have a hash of Users based on their websocket id. When a user makes the following request i'd like to add them to a group of users viewing that page.
app.get('/board/:id', function(req, res){}
I'd like to keep something like
Browsing = {
username : id,
username : id,
...
}
However i'm unsure how to remove a user lets say if they navigate off the page. Is there some kind of function that gets called upon page leave?
Partial Solution:The following seems to do the trick on Chrome:
$(window).unload(function(){
var username = $('#username').text();
var pid = currentProject;
var data = {
username: username,
id : pid
}
socket.emit('leaving-page', data);
})
... Is there some kind of function that gets called upon page
leave? ...
Yes, but it is not reliable.
The way the people keep track of who is online and who isn't, is usually like this:
Add the time when the user last refreshed/visited a page
set a limit to you consider them offline
You could intercept the event which corresponds to leaving a page. There are several ways to do it, have a look at the following links and let me know if any suits your needs and if I can answer any more explicit questions about them:
Intercept page exit event
Best way to detect when a user leaves a web page?
jquery unload
with the last link you could do something like this:
$(window).unload(function() {
//remove the user from your json object with delete json_object[key];
});
Hope this helps.
Since you're using Socket.io, the server will know when the user has left the page because the socket will be disconnected. Simply listen for the disconnect event.
io.sockets.on('connection', function (socket) {
...
socket.on('disconnect', function () {
// The user on `socket` has closed the page
});
});
Better yet, take advantage of namespaces and let Socket.io handle all of the connection/disconnection (it's doing it anyway -- no need to duplicate effort).
On the client,
socket = io.connect('http://example.com/pagename');
pagename need not point to a valid URL on your domain – it's just the namespace you'll use in the server code:
io.sockets.clients('pagename')
Gets you all of the clients currently connected to the pagename namespace.

Categories