Handling browser window close in a nowjs chat application - javascript

I am creating a chat application with nowjs.User can create a chatroom and then invite users to that room.Following is the code used to do this:
everyone.now.addPeopleToChat = function(clientIds,roomName) {
var length = clientIds.length;
var group = nowjs.getGroup(roomName);
for(var i=0;i<length;i++){
group.addUser(clientIds[i]);
}
group.now.roomName = roomName;//User can be in one room only at any given time.Reference to the roomname to be used when user leaves chat
group.now.loadChatWindow();//Load UI
}
So far so good.Users are able to be added to chat room and chatting is also fine.
When a user is in a chat room and he closes the browser window,I want other users in the chat room to be made aware that this person has left the chat.I thought of using the disconnect event to handle this particular situation.This is the code I have used.
nowjs.on('disconnect', function () {
console.log("User name:"+this.now.name);//comes fine
console.log("Room name:"+this.now.roomName);//shows undefined.
var group = nowjs.getGroup(this.now.roomName);//Intention is to get the room in which user was chatting.But it is not working because roomName is undefined.
group.now.broadcast(this.now.name+" has left this room");
});
Why is that roomName is shown as undefined in disconnect handler.I am setting that variable when the users are added to the group right.So each of the user in the group should have that variable set right.Am I missing something here?

Related

RTCMultiConnection users streams keeps alive

Im using webRTC plugin named (RTCMultiConnection) but if user has his cam on and leave somehow his session stays alive. Because if user1 opens cam, than leaves, again comes back and opens cam than it's not able to join it's cam.
Im trying to append the new connections like;
Webcam.connection.onNewSession = function(session) {
console.log("On new session")
createSession: function(session){
Webcam.sessions[session.sessionid] = session;
$("div").append($("<div />", {
class: "webcam-live ct icon-isight",
html: "LIVE"
}));
}
};
First time opening the cam it appends whenever same user leaves and comesback it doesnt trigger for others. But if take another username than it sends its to new users
Source

Preserving web sockets with Laravel and JavaScript

I am currently using Ratchet with laravel 4 for my application's chat feature. I am using the following JS in the front-end to handle the web sockets.
function startChatSession(){
var person = prompt("Please enter your ID", "");
if(chatBoxes.length <= 0)
chatBoxes.push("onlineList");
if (person != null && person != "") {
myself = person;
if(conn == null){
conn = new WebSocket('ws://192.168.1.5:8080?'+person); // 'user facebook id' instead of name
conn.onmessage = msgReceive;
conn.onopen = function(e) {
console.log(e);
};
conn.onerror = function(e){setTimeout(startChatSession,5000);};
}
}
}
Now my problem is that the web socket connection disconnects on page refresh and page transition. After searching the web I decided this couldn't be fixed in the front-end. So I want to preserve the chat session at the Laravel's end. I am already storing the online users in the DB, when a connection is opened and deleting them on close.
I am trying to come up with a work around check for online users, since the sockets opens and closes often it creates too many inserts and deletes to table. How can I attach the socket with Laravel session or create a work-around that could solve my problem?

simpleWebRTC with php backend

I am using simpleWebRTC with xhr to implement peculiar multi-users video chat (no audio)
my main issue in short: i was unable to attach the username from php to the correct video in JS
in my quetion i will
1. explain what i have done - and what are my current issues
2. if my current route is impossible - then i ask for suggestions for a different course of action on my part :-) - my knowledge is in JS and PHP|
the multi-users video allows to chose a few users and see them in a one way connection.
lets say we have users A, B, C, D
user A chooses to see users B, C, D while user B for example only chooses to see users C and D .... and so on
in simpleWebRTC i thought of two courses of action
a. one room for all of the participants and then to filter them down (was unsuccessful as i was unable to attach the correct username to each video - to filter them out)
2. instead i created a room (with username - email, as id) and let each user connect to the appropriate room.
in the first part of the code i have an XHR that pulls a list of the people the user wishes to subscribe to there videos (i.e: chooses to see)
var remoteRoom = [];
$.get('scripts/video/ours/musesSimpleList.php', function(msg){
myRoom = msg.username;
var remoteRoomArray = $.each( msg.museUsername, function(key, value){
remoteRoom.push = value;
return remoteRoom;
});
afterRoomDefined(myRoom, remoteRoomArray);
}, 'json');
function afterRoomDefined(myRoom, remoteRoomArray) is called after the list of people this specific user chose to register to was retrieved from MySQl
in this function, i now try to implement the WebRTC:
function afterRoomDefined(myRoom, remoteRoom){
console.log('remote room name: '+ remoteRoom + ' type: '+ $.type(remoteRoom));
remoteRoom = JSON.stringify(remoteRoom);
console.log('isArray '+$.isArray(remoteRoom));
//Create our WebRTC connection
var webrtc = new SimpleWebRTC({
url:'https://signaling.simplewebrtc.com:443',
//the element that will hold the local video
localVideoEl: 'localVideo',
//the element that will hold remote videos
//remoteVideosEl: 'remotes',
remoteVideosEl: '',
autoRequestMedia: true,
media: {
video: true,
audio: false
},
});
webrtc.mute();
// a peer video has been added
var i = 0;
//When it's ready and we have a room from the URL, join the call
webrtc.on('readyToCall', function(peer){
//each user first creates a room for himself - so other users could connect to
if(myRoom) webrtc.joinRoom(myRoom);
//here a room is created for every person the user subscribed to. each person created a room with his own username (when he opened this page in his browser) - in the line above. so now i open rooms with the same names - so the users will see each other (two ways now)
for(var b=0; b<remoteRoom.museUsername.length; b++){
console.log('remoteRoom loop - separate values: '+ remoteRoom.museUsername[b]);
if(remoteRoom.museUsername[b]) webrtc.joinRoom(remoteRoom.museUsername[b]);
}
});
// a peer video has been added
webrtc.on('videoAdded', function (video, peer) {
var remotes = document.getElementById('remotes');
if (remotes) {
var container = document.createElement('div');
container.className = 'videoContainer'+i;
$(container).attr('data-username', remoteRoom.museUsername[i]);
i++;
container.id = 'container_' + webrtc.getDomId(peer);
container.appendChild(video);
// suppress contextmenu
video.oncontextmenu = function () { return false; };
remotes.appendChild(container);
//this is to remove the other party video - if a user only subscribed to another user - the other user is not
//$('#remotes div:not[data-username]').css('border', 'red 5px solid');
$('#remotes div:not[data-username]').remove();
}
i=i+1;
});
webrtc.on('videoRemoved', function (video, peer) {
var remotes = document.getElementById('remotes');
var el = document.getElementById(peer ? 'container_' + webrtc.getDomId(peer) : 'localScreenContainer');
$('#remotes div').css('border', '#F4171A 2px solid');
if (remotes && el) {
remotes.removeChild(el);
}
});
That's it. and that basically works.
There are three issues though:
a. when one of the users refreshes his page (usually navigate back an forth) his own video is added again (two videos of the same user now - one of them is frozen) to all the other users who watches him. perhaps its an issue with
webrtc.on('videoRemoved'...
b. when user A for example registers to user B... - if user C than subscribes to user A - he will see also user B
the main issue perhaps is:
c. i was never really able to attach the username to the right video under:
webrtc.on('videoAdded',....
$(container).attr('data-username', remoteRoom.museUsername[i]);...
in the main block code.
I used
$('#remotes div:not[data-username]').remove();
to find all videos without username and kick (videos who were duplicated and froze+the other side of the video if user A subscribed to user B and not vice versa so user B will not see user A and so that C will not see in the above explanation) them out - but the username it self is not attached to the correct child in the right order (the moment someone refreshes the page the order scrambles....
am i going the right direction?
i had a look at pubNub, xirsys, firebase and some other solutions
(google appengine - java knowledge required, html5Rocks, easyRTC, signalMaster (no proper explanation on how to use)- but it seems that they all require node.js )
is my current mode of action (php and XHR) is a valid one?
if not - will one of the other solution will be relatively simple and plausible.
I started looking through too many api's and am confused by now
thank you :-)
It's hard to see exactly what goes wrong, because you seems to face multiple issue here, including webRTC in general and DOM insertion/removal problems.
If you are seeking for webRTC solution using PubNub, you should take a look at:
https://github.com/stephenlb/webrtc-sdk
and the demo that you can try:
http://stephenlb.github.io/webrtc-sdk/
also, check out
http://www.pubnub.com/blog/building-a-webrtc-video-and-voice-chat-application/

Adding chat functionality to website

I've been able to add chat functionality to my website but I'm wondering if there is a more efficient way to do it. This is the current structure of the chat:
HTML page with javascript functions:
sendChat(elmnt) {
var result = XHR("http_sendChat.aspx","POST",0,elmnt); //xmlhttprequest to send chat message by posting elmnt string to page. 0 used for not polling
}
getChat() {
var result = XHR("http_getChat.aspx","GET",50,""); //polls page every 50ms to get new chat messages
addMessageElmnt(result); //update chat window with new messages
}
On the server side in vb.net http_sendChat.aspx:
Application.Lock
Application("chat") = Application("chat") & Request.Form("message") //Global application object stores chat log
Application.Unlock
On the server side in vb.net http_getChat.aspx:
Dim chatTemp
chatTemp = Mid(Application("chat"),Session("chatIndex")) //fetches whatever chat data hasn't been fetched yet
Session("chatIndex") = Session("chatIndex") + Len(chatTemp) //set index to last read position
Response.Write(chatTemp)
There is some more code that mostly checks to make sure the users account is activated and such but as far as the chat goes, is there a better way to do this? I ask because its fairly slow when there are like 100 people logged in and using the chat.

Titanium - prevent exitOnClose from stopping the app

My app uses the gcm module to listen for notifications and displays android notifications for every new notification that comes in. Additionally, the current window gets updated with the new count of unread messages.
This window is created using Ti.UI.createWindow({exitOnClose:true})
The problem is, that when the user presses the back button, the application stops. This means, I don't receive any more notifications and thus cannot display them in the notifications bar.
Is there a way to make titanium hide the app when pressing the back button, but not stop it, so that my code stil is running in the background?
I know of the possibility to start a service, but the downside of this is that i cannot update my window, when it's currently visible to the user, since there seems to be no way to communicate between the service and the app. Or is there a way?
app.js
//this is the most important line in this code.
//if I do exitOnClose:true, I stop receiving notifications every 5 seconds when pressing the back button (not good!, I want to keep getting notifications)
//if I do exitOnClose:false, I go back to a blank, "powered by titanium" window, when pressing the back button (not good!, I want the app to go to the background)
var win = Ti.UI.createWindow({exitOnClose:true});
//not part of the question
var label = Ti.UI.createLabel({text:"0"});
win.add(label);
win.open();
var notifications = [];
//listen for notifications (not part of the question)
listenForNotifications(function(notification){
//handle the notification
notifications.push(notification);
//update window
label.text = "Notification Count: "+notifications.length;
//display notification in title bar
displayNotificationInTitleBar(notification);
})
//this function is just dummy code to simulate listening for notifications in background using the gcm module
//it simulates a new notification every 5 seconds with an always increasing id
//it actually does not matter what module I use for notifications, Just take it as given that there runs code in the background,
//that I don't want to stop, after the user taps the backbutton
function listenForNotifications(cb){
var i = 0;
setInterval(function(){
cb({id:i++});
},5000);
}
//This function is actually not part of the question, it's just a sample
function displayNotificationInTitleBar(notification){
var intent = Ti.Android.createIntent({
action: Ti.Android.ACTION_MAIN,
packageName:"com.company.backgroundnotificationstest",
className:"com.company.backgroundnotificationstest.BackgroundnotificationstestActivity",
flags:Ti.Android.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Ti.Android.FLAG_ACTIVITY_SINGLE_TOP
});
intent.addCategory(Ti.Android.CATEGORY_LAUNCHER);
intent.putExtra("notificationid",notification.id);
Titanium.Android.NotificationManager.notify(notification.id, Titanium.Android.createNotification({
contentTitle: "New Notification",
contentText : "ID: "+notification.id,
contentIntent: Ti.Android.createPendingIntent({
intent:intent,
type : Ti.Android.PENDING_INTENT_FOR_ACTIVITY
}),
flags : Titanium.Android.ACTION_DEFAULT | Titanium.Android.FLAG_AUTO_CANCEL | Titanium.Android.FLAG_SHOW_LIGHTS
}));
}
The sample app is available at: https://github.com/VanCoding/TitaniumBackgroundNotificationsTest
Feel free to compile it and see it yourself :)
Since you set exitOnClose your app will exit on closing the window you have created. To prevent exiting from the app you need to reset the key as follows while creating the window.
Ti.UI.createWindow({exitOnClose: false});
If you would like to show the notifications in the notifications tray, make sure that you have set the following keys
showTrayNotification
showTrayNotificationsWhenFocused : This will display the notification in the tray even when the app is focused.
To show/hide a badge, you can try the following tip.
You need to keep track how many notifications you received and you need to update it upon receiving the notification. Just update the badge using the value stored. I tried this solution and is working great in one of my app
After a bit of thinking, I came to the following (a bit hacky) solution:
win.addEventListener("android:back",function(){ //listen for the back-button-tap event
e.cancelBubble = true; //prevent the back-button default action
//display the home screen
var intent = Ti.Android.createIntent({
action: Ti.Android.ACTION_MAIN,
flags:Ti.Android.FLAG_ACTIVITY_NEW_TASK
});
intent.addCategory(Ti.Android.CATEGORY_HOME);
Ti.Android.currentActivity.startActivity(intent);
});

Categories

Resources