Problems with multiple websockets (over time) - javascript

TLDR: My websockets stop connecting after a while, though they work perfectly at first. How do I fix it?
I have a C# web service that makes use of two websockets (via websocket-sharp). They are defined like so:
public WebSocketServer sock1= new WebSocketServer("ws://localhost:802");
sock1.Log.Level = WebSocketSharp.LogLevel.Error;
sock1.Log.File = "LOG\\logfile.LOG";
sock1.AddWebSocketService<StatusWebSocket1>("/");
sock1.KeepClean = false;
sock1.Start();
public WebSocketServer sock2= new WebSocketServer("ws://localhost:803");
sock2.Log.Level = WebSocketSharp.LogLevel.Error;
sock2.Log.File = "LOG\\logfile.LOG";
sock2.AddWebSocketService<StatusWebSocket2>("/");
sock2.KeepClean = false;
sock2.Start();
These websocket servers accept client connections from my angularjs app:
$scope.socket = null;
var startStopPolling = function(action){
if(action == 'close'){
$scope.socket.close(3001, 'User leaving page.');
return;
}
var path = 'ws://' + window.location.hostname + ':802/';
$http({method: 'GET', url: apiRoot+'is-remote', timeout: 1000})
.success(function(response) {
path = 'wss://' + window.location.hostname + '/';
}).finally(function(){
$scope.socket = new WebSocket(path);
$scope.socket.onerror = function(event){
console.log('SOCKET ERROR', event);
$timeout(startStopPolling, 1000);
};
$scope.socket.onopen = function(){
var selfInfo = {
locationCode: $scope.LocationCode,
token: BrowserStorageService.get('token'),
type: 'ClientRegistration',
mode: 'status'
};
$scope.socket.send(JSON.stringify(selfInfo));
$scope.socket.onmessage = function(event){
var data = JSON.parse(event.data);
//do some stuff with data
});
};
};
});
};
startStopPolling();
And elsewhere:
var socket2 = null;
var startStopPolling2 = function(action){
if(action == 'close'){
socket2.close(3001, 'App closing.');
return;
}
var path2 = 'ws://' + window.location.hostname + ':803/';
socket2 = new WebSocket(path2);
socket2.onerror = function(event){
console.log('SOCKET ERROR', event);
$timeout(startStopPolling2, 1000);
};
socket2.onopen = function(){
var selfInfo = {
mode: 'status2',
type: 'ClientRegistration'
};
socket2.send(JSON.stringify(selfInfo));
socket2.onmessage = function(event){
var data = JSON.parse(event.data);
console.log('status2', data.status2);
if(data.status2 == "Closed"){
$state.go("status");
}
};
};
};
startStopPolling2();
$rootScope.$on('$destroy', function(){
startStopPolling2('close');
});
The application mostly sits on one page. (We display a status page most of the time, but allow the user to navigate away to do things like manage configuration.) When we receive a certain status value from the status2 socket (socket2), we want to do some things, so we have to keep track of that all the time. The other socket is only relevant when on that page, so we want to get rid of it when we don't need it.
Here's the problem: The app periodically refreshes the page via a call like location.reload(true). Wile it works perfectly at first, after so many of these refreshes, the sockets no longer connect. There are no errors in the console, and neither onOpen() function fires. What's going on, and how do I fix it?

Related

Authorize.net embedded iFrame accept.js response transaction

I have integrated authorize.net accept.js embedded iFrame in my application. Having trouble setting the transaction respone in my lambda function to get the response. I've seen similar questions on stack overflow but nothing worked out for me yet.
Using Nodejs for my backend and angular7 for the front-end.
I successfully get the token from my lambda function so my iframe appears on the ui. I've set \"showReceipt\": false providing url for cancel & continue, since the documentation says I have to set the show receipt parameter "false" in order to communicate with the IFrameCommunicator.html in the ui. But when I click on "Pay" its stuck at "Processing.." for a long time.
Following are the request & response headers respectively from the network tab:
* Cookie: __cfruid=deb63d2f12d9690aeea838cf7f31ada6da92bc1c-1602260930
* Host: test.authorize.net
* Origin: https://test.authorize.net
* Referer: https://test.authorize.net/payment/payment
* Sec-Fetch-Dest: empty
* Sec-Fetch-Mode: cors
* 
Sec-Fetch-Site: same-origin
{"resultCode":"Ok","messageCode":"Ok","transactionData":{"accountType":"Discover","accountNumber":"XXXX0012","transId":"40055282319","responseCode":"4","authorization":"TYIUU7","merchantName":"iMart Inc.","totalAmount":"1999.9","dateTime":"10/09/2020 4:20:27 PM"}}
I'm sure the transaction is happening looking at the response but not sure why it's not connecting with the communicator.
I've read the steps in the documentation and also followed the GitHub sample code-https://github.com/AuthorizeNet/accept-sample-app, which made me more confused since they both say different things at some places. Following are the steps I've accomplished until now :
Created a lambda hosted payment function with all the settings (followed the correct sequence) to get back a token.
Created a hosted payment form to display the iframe.
Able to make a payment --> get the receipt page --> routing to success screen.
What I'm trying to accomplish:
After I make the payment, initial idea was to trigger a different lambda function based on the response from authorize.net without communicating with IFrameCommunicator.html, but as I cannot do that, I want to get a response to initiate the next process at the backend.
Also, we're not storing any user details in our server and not interested in creating a customer profile unless it's a necessary step to get the transaction response. Please suggest the step integration if I can do it in the same lambda function I've created to get a token or I would have to create a different one for this and when will that step be implemented?
I know about the Webhooks but not sure if it's an absolute necessity at this point of time when I'm just trying to implement a simple transaction.
I'm a newbie and I couldn't find a lot of examples related to the same to resolve my issues/confusions. Would highly appreciate if I get a clear explanation on the steps here and where am I going wrong.
Following is the code -
accept-hosted.js Lambda function:
merchantAuthenticationType.setName('*****');
merchantAuthenticationType.setTransactionKey('******');
var transactionRequestType = new ApiContracts.TransactionRequestType();
transactionRequestType.setTransactionType(ApiContracts.TransactionTypeEnum.AUTHCAPTURETRANSACTION);
transactionRequestType.setAmount(Total);
var setting1 = new ApiContracts.SettingType();
var setting2 = new ApiContracts.SettingType();
var setting4 = new ApiContracts.SettingType();
var setting5 = new ApiContracts.SettingType();
var setting6 = new ApiContracts.SettingType();
var setting7 = new ApiContracts.SettingType();
var setting8 = new ApiContracts.SettingType();
var setting9 = new ApiContracts.SettingType();
var setting10 = new ApiContracts.SettingType();
var setting11 = new ApiContracts.SettingType();
setting2.setSettingName("hostedPaymentButtonOptions");
setting2.setSettingValue("{\"text\": \"Pay\"}");
setting1.setSettingName("hostedPaymentReturnOptions");
setting1.setSettingValue(
"{\"showReceipt\": false, \"url\": \"https://iMart.com/success.html\", \"urlText\": \"Continue\", \"cancelUrl\": \"https://iMart.com/error.html\", \"cancelUrlText\": \"Cancel\"}");
setting10.setSettingName("hostedPaymentOrderOptions");
setting10.setSettingValue("{\"show\": false, \"merchantName\": \"iMart Inc.\"}");
setting5.setSettingName("hostedPaymentPaymentOptions");
setting5.setSettingValue("{\"cardCodeRequired\": true, \"showCreditCard\": true, \"showBankAccount\": false}");
setting7.setSettingName("hostedPaymentShippingAddressOptions");
setting7.setSettingValue("{\"show\": false, \"required\": false}");
setting8.setSettingName("hostedPaymentBillingAddressOptions");
setting8.setSettingValue("{\"show\": false, \"required\": false}");
setting6.setSettingName("hostedPaymentSecurityOptions");
setting6.setSettingValue("{\"captcha\": true}");
setting4.setSettingName("hostedPaymentStyleOptions");
setting4.setSettingValue("{\"bgColor\": \"blue\"}");
setting9.setSettingName("hostedPaymentCustomerOptions");
setting9.setSettingValue("{\"showEmail\": false, \"requiredEmail\": false, \"addPaymentProfile\": true }");
setting11.setSettingName("hostedPaymentIFrameCommunicatorUrl");
setting11.setSettingValue("{\"url\": \"https://iMart.com/IFrameCommunicator.html\"}");
var settingList = [];
settingList.push(setting2);
settingList.push(setting10);
settingList.push(setting5);
settingList.push(setting7);
settingList.push(setting8);
settingList.push(setting6);
settingList.push(setting4);
settingList.push(setting9);
settingList.push(setting11);
settingList.push(setting1);
var alist = new ApiContracts.ArrayOfSetting();
alist.setSetting(settingList);
var firstname = new ApiContracts.UserField();
firstname.setName('First Name');
firstname.setValue(firstName);
var lastname = new ApiContracts.UserField();
lastname.setName('Last Name');
lastname.setValue(lastName);
var userFieldList = [];
userFieldList.push(firstname);
userFieldList.push(lastname);
var userFields = new ApiContracts.TransactionRequestType.UserFields();
userFields.setUserField(userFieldList);
var transactionSetting1 = new ApiContracts.SettingType();
transactionSetting1.setSettingName('duplicateWindow');
transactionSetting1.setSettingValue('120');
var transactionSetting2 = new ApiContracts.SettingType();
transactionSetting2.setSettingName('recurringBilling');
transactionSetting2.setSettingValue('false');
var transactionSetting3 = new ApiContracts.SettingType();
transactionSetting3.setSettingName('emailCustomer');
transactionSetting3.setSettingValue('true');
var transactionSetting4 = new ApiContracts.SettingType();
transactionSetting4.setSettingName('headerEmailReceipt');
transactionSetting3.setSettingValue('You are all set!');
var transactionSetting5 = new ApiContracts.SettingType();
transactionSetting5.setSettingName('footerEmailReceipt');
transactionSetting5.setSettingValue('This is the footer');
var getRequest = new ApiContracts.GetHostedPaymentPageRequest();
getRequest.setMerchantAuthentication(merchantAuthenticationType);
getRequest.setTransactionRequest(transactionRequestType);
getRequest.setHostedPaymentSettings(alist);
var ctrl = new ApiControllers.GetHostedPaymentPageController(getRequest.getJSON());
const basicAuth = encode.encode("*****", 'base64');
await axios({
method: 'post',
url: 'https://apitest.authorize.net/xml/v1/request.api',
headers: {
'Authorization': 'Basic '+basicAuth,
'Content-Type': 'application/json'
},
data:JSON.stringify(ctrl._request)
}).then(async (data : any)=>{
if(data.data.token) {
callback(null, data.data) ;
} else callErr(data);
});
async function callErr(data: any){
callback(null, res) ;
}
}
IFrameCommunicator.html:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Iframe Communicator</title>
<script type="text/javascript">
//<![CDATA[
function callParentFunction(str) {
if (str && str.length > 0
&& window.parent
&& window.parent.parent
&& window.parent.parent.AuthorizeNetPopup
&& window.parent.parent.AuthorizeNetPopup.onReceiveCommunication)
{
// Errors indicate a mismatch in domain between the page containing the iframe and this page.
window.parent.parent.AuthorizeNetPopup.onReceiveCommunication(str);
}
}
function receiveMessage(event) {
if (event && event.data) {
callParentFunction(event.data);
}
}
if (window.addEventListener) {
console.log('addEventListener');
console.log(receiveMessage);
window.addEventListener("message", receiveMessage, false);
} else if (window.attachEvent) {
window.attachEvent("onmessage", receiveMessage);
}
if (window.location.hash && window.location.hash.length > 1) { callParentFunction(window.location.hash.substring(1));
}
//]]/>
</script>
</head>
<body>
</body>
</html>
Angular code for showing the iFrame:
<iframe id="add_payment" class="embed-responsive-item panel" name="add_payment" width="100%" frameborder="0" scrolling="yes">
</iframe>
</div>
<form id="send_token" action="" method="post" target="add_payment" >
<input id="token" type="hidden" name="token" />
</form>
I have been struggling a lot since many days now with a time crunch. Would be really helpful if someone provides me with a good insight here. Please let me know if additional info is required. Thank you in advance!!!
Here are the answer for all your question, I hope it works :
1)if you are using iFrame then iFrameCommunicator is mandatory
2)the success url can only be used when you set "showReceipt" as true, here you cannot navigate automatically to yoour success page, this is the link for "Continue" button which appears when "showReceipt" is allowed
3)If you want to trigger any function or want to navigate after the response then add the following code in your html file
<script type="text/javascript">
$(document).ready(function () {
window.CommunicationHandler = {};
function parseQueryString(str) {
var vars = [];
var arr = str.split('&');
var pair;
for (var i = 0; i < arr.length; i++) {
pair = arr[i].split('=');
vars[pair[0]] = unescape(pair[1]);
}
return vars;
}
window.CommunicationHandler.onReceiveCommunication = function (argument) {
console.log('communication handler enter', argument);
var params = parseQueryString(argument.qstr)
switch (params['action']) {
case "resizeWindow":
console.log('resize'); break;
case "successfulSave":
console.log('save'); break;
case "cancel":
console.log('cancel'); break;
case "transactResponse":
sessionStorage.removeItem("HPTokenTime");
console.log('transaction complete');
var transResponse = JSON.parse(params['response']);
console.log('transaction complete1', transResponse);
// window.location.href = '/checkout/complete';
}
}
//send the token
$('#send_hptoken').submit();
});
</script>

jQuery HTTP Post stopped working, only works when long strings are input

Quick background: Very new to web development. I have a bootstrap page with a form which users can fill out. There are four fields (two text boxes, one radio, one dropdown). The idea was to form a JSON using that input data and POST it to my HTTP server, but it doesn't seem to be working anymore.
Very strange, my code was working perfectly a few hours ago (have been testing with requestb.in).
Now all of a sudden it (1) only sends the POST if I have long values for the apiname and apiurl variables, and (2) no longer sees what I've chosen from the radio checkboxes (env1 - env3), and instead always thinks I've chosen 'Dev,' regardless of what was actually selected.
I'm assuming my issues are caused by the jQuery in my code and not the HTML, so I've attached that here:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$("button").click(function(){
var env1 = document.getElementById("seldevid");
var env2 = document.getElementById("selstageid");
var env3 = document.getElementById("selprodid");
var apiname = $("#apinameid").val();
var apiurl = $("#apiurlid").val();
var actionvar;
$("#actionid").change(function() {
actionvar = $(this).val();
}).change();
if (env1.checked = true) {
var env = "Dev";
} else if (env2.checked = true) {
var env = "Stage";
} else if (env3.checked = true) {
var env = "Prod";
}
$.post("http://requestb.in/107fmof1",
{
apiName: apiname,
apiURL: apiurl,
environment: env,
action: actionvar
},
function(data,status){
alert("Data: " + data + "\nStatus: " + status);
});
});
});
</script>
Thanks for the help!
First Question: Why Always "Dev"?
The issue is in your if statements you have used an assignment, rather than a boolean comparison. You need to use == to compare the two values for equality. Instead you are setting env1.checked = true, which evaluates to true, so env is always being set to "Dev".
if (env1.checked == true) {
var env = "Dev";
} else if (env2.checked == true) {
var env = "Stage";
} else if (env3.checked == true) {
var env = "Prod";
}
or even
var env;
if (env1.checked) {
env = "Dev";
} else if (env2.checked) {
env = "Stage";
} else if (env3.checked) {
env = "Prod";
}
Second Question: Why not posting?
You should try simplifying your code a bit:
$(document).ready(function(){
var env1 = document.getElementById("seldevid");
var env2 = document.getElementById("selstageid");
var env3 = document.getElementById("selprodid");
$("button").click(function(){
var env = "Dev";
if (env2.checked) {
env = "Stage";
} else if (env3.checked) {
env = "Prod";
}
$.post("http://requestb.in/107fmof1",
{
apiName: $("#apinameid").val(),
apiURL: $("#apiurlid").val(),
environment: env,
action: $("#actionid").val()
},
function(data,status){
alert("Data: " + data + "\nStatus: " + status);
}
);
});
});
Then using the browser Developer Tools to see what exactly is being POST'd, if anything.

How to insert form into mysql without leaving the page (javascript+html)

I'm trying to insert a new user into mysql. I have tried to use jQuery, but it doesn't seem to be working. I tried to use pure javascript, but it's the same. It has no response after I click on the button. What's wrong?
var regBtn = document.getElementById("regBtn");
regBtn.addEventListener("click", submitForm, false);
function submitForm() {
var acR = document.getElementById("ac2");
var pw1 = document.getElementById("pw1");
var shop = document.getElementById("shop");
var http = new XMLHttpRequest();
http.open("POST", "http://xyz.php", true);
http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
var params = "ac=" + acR + "&pw1="+pw1 "&shop="+ shop;
http.send(params);
http.onload = function() {
alert(http.responseText);
};
}
There's a quite a few problems in your JS code, I've tidied it up here and run it locally to a page called xyz.php, so that'll get the AJAX call to work but you'll need to post your PHP code to get any help with your DB queries
var regBtn = document.getElementById("regBtn");
regBtn.addEventListener("click", submitForm, false);
function submitForm() {
var acR = document.getElementById("ac2");
var pw1 = document.getElementById("pw1");
var http = new XMLHttpRequest();
// removed the http:// protocol, assuming you're going for a local AJAX call
http.open("POST", "xyz.php", true);
http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// get values of the form fields, don't submit the full element
// also added the plus (+) character before the final pw1
var params = "ac=" + acR.value + "&pw1=" + pw1.value;
http.send(params);
http.onload = function() {
alert(http.responseText);
}
}
I've attached a screen shot showing Chrome Dev Tools happily recording successful AJAX requests
Try to use a JQuery post.
var acR = document.getElementById("ac2");
var pw1 = document.getElementById("pw1");
$.post( "xyz.php", { ac: acR, pw1: pw1 })
.done(function( data ) {
alert( "Data inserted: " + data );
});
Backend handles this post and then implement the insert action for example in NodeJs(express)
app.post("/xyz", function(req, res, next) {
var obj = {};
obj[acR] = body.ac;
obj[pw1] = body.pw1;
mysql.insert(obj);
});

How would I make user wait to join until meeting organizer joins first

I am implementing a video conference room in which a user can create a video conference and invite other users.
Now I want to make sure that the user can't join the conference until the meeting organizer opens the room.
I have the following code but it is not working. The meeting organizer can open the room but when users click on "join conference" it doesn't join.
// https://github.com/muaz-khan/RTCMultiConnection
var rmc = new RTCMultiConnection();
rmc.userid = "<?php echo $user->fname . ' ' . $user->lname . ' (' . $user->username . ')' ; ?>";
rmc.session = {
video: true,
audio: true,
data: true
};
var room_status = 0; //room closed
$('#open-room').click(function () {
// http://www.rtcmulticonnection.org/docs/open/
room_status = 1; //room opened
rmc.open();
rmc.streams.mute({video : true});
document.getElementById("on-off-video").style.color= 'red';
});
$('#join-room').click(function () {
if(room_status == 1) {
// http://www.rtcmulticonnection.org/docs/connect/
rmc.connect();
rmc.streams.mute({video: true});
document.getElementById("on-off-video").style.color= 'red';
}
console.log("Waiting for meeting organizer");
});
// display a notification box
window.addEventListener('beforeunload', function () {
return 'Do you want to leave?';
}, false);
// leave here
window.addEventListener('unload', function () {
rmc.leave();
}, false);
rmc.onMediaCaptured = function () {
$('#share-screen').removeAttr('disabled');
$('#open-room').attr('disabled', 'disabled');
$('#join-room').attr('disabled', 'disabled');
};
//chat
rmc.onopen = function (event) {
//alert('Text chat has been opened between you and ' + event.userid);
document.getElementById('input-text-chat').disabled = false;
room_status = 1;
};
//end of chat
$('#disconnect').click(function () {
room_status = 0; //room closed
rmc.leave();
setTimeout("location.href = '../';",2000);
});
//to know the stream type
rmc.onstream = function (e) {
if (e.type == 'local') {
// alert("the stream is local");
}
if (e.type == 'remote') {
// alert("the stream is remote");
}
if (e.isVideo) {
var uibox = document.createElement("div");
uibox.appendChild(document.createTextNode(e.userid));
uibox.className = "userid";
uibox.id = "uibox-" + e.userid.replace(/ |\(|\)/g, '');
document.getElementById('video-container').appendChild(e.mediaElement);
document.getElementById('video-container').appendChild(uibox);
}
else if (e.isAudio) {
document.getElementById('video-container').appendChild(e.mediaElement);
}
else if (e.isScreen) {
$('#cotools-panel iframe').hide();
$('#cotools-panel video').remove();
document.getElementById('cotools-panel').appendChild(e.mediaElement);
}
};
//removes the div containing the userid of the user who is leaving
rmc.onleave = function (e) {
$('#' + "uibox-" + e.userid.replace(/ |\(|\)/g, '')).remove();
};
It seems you have 3 problems here.
1) First, I think you can't use only one RTCMultiConnection object to open and join a room. You have to create 2 separate objects. But, your code is not supposed to run in the same window for opening and joining the room. So It's not a problem if you run it once in a window to open the room and one in another window to join it.
In this case you have a more important problem. Your variable room_status is set to 1 when you open the room in one window. But in the other window, room_status is still equals to 0 so you don't call the code inside the if() in $('#join-room').click function.
It's not a big deal, for now, let's delete the if statement to be sure your code is executed (and read my point 3 for your original goal).
2) I look to the simple example given on https://github.com/muaz-khan/RTCMultiConnection : https://jsfiddle.net/c46de0L8/ and it seems you should use join and not connect. And above all, you should use a Channel ID and a Room Id to be able to connect 2 users.
So I change your code a little and it seems to work well :
var CHANNEL_ID = "MYCHANNEL-" + window.RMCDefaultChannel;
var ROOM_ID = "MYROOM";
var SESSION = {
video: true,
audio: true,
data: true
};
var USERID = "<?php echo $user->fname . ' ' . $user->lname . ' (' . $user->username . ')' ; ?>";
var rmc = undefined;
var room_status = 0; //room closed
$('#open-room').click(function () {
// http://www.rtcmulticonnection.org/docs/open/
room_status = 1; //room opened
rmc = new RTCMultiConnection(CHANNEL_ID);
rmc.userid = USERID;
rmc.session = SESSION;
rmc.open({
dontTransmit: true,
sessionid: ROOM_ID
});
rmc.streams.mute({video : true});
document.getElementById("on-off-video").style.color= 'red';
});
$('#join-room').click(function () {
//if(room_status == 1) {
// http://www.rtcmulticonnection.org/docs/connect/
rmc = new RTCMultiConnection(CHANNEL_ID);
rmc.join({
sessionid: ROOM_ID,
userid: USERID,
session: SESSION
});
rmc.streams.mute({video: true});
document.getElementById("on-off-video").style.color= 'red';
//}
console.log("Waiting for meeting organizer");
});
The rest of the code remains unchanged.
I put a rough working code in a JSFiddle: https://jsfiddle.net/sebdoncker/fjtkvnjq/2/
3) Now you still have the problem : How to be sure that the room is opened before to be able to join it. I think you can use the ROOM ID for this. When one user open a new room you should generate a ROOM ID. Now, you have to send this ROOM ID to your joiner user (by server communication or another way depending of your application architecture). And Since the joiner user doesn't have the ROOM ID, you can disable the join button.
It's just a lead, this depends of your overall application architecture.

Javascript callbacks work in Firefox but not in Chrome or Safari

I am working with Ejabberd and Orbited and I am having a few issues with my JavaScript callback functions not being called. The following is my JavaScript file where the TCPSocket connection happens and I have two callback functions namely
onSocketConnect: which is called when the Orbited established connection with port 5222 of the XMPP server and
onLoginSuccess: which is called on the successful completion of the xmpp_client.login function
The problem I'm facing is the connection happens successfully but my callbacks get called only when I'm using FireFox and not while using Safari or Chrome. I'm totally clueless about what is causing this problem but I'm sure that the method xmpp_client.login does get called because the user is logged in and is displayed as online in the ejabberd admin console.
TCPSocket = Orbited.TCPSocket;
Orbited.settings.port = 8000;
Orbited.settings.hostname = 'localhost';
document.domain = document.domain;
<script src='http://localhost:8000/static/protocols/xmpp/xmpp.js'></script>
//xmpp.js file is included after this which is available with the Orbited. I have not included the code here.
<% if current_user %>
<script>
notifier = ' ';
user = "<%= current_user.jabber_id %>";
alert(user);
password = '123456';
domain = XMPPDOMAIN;
/* function onLoginSuccess(){
$('.status').html("Connected and Logged In");
xmpp_client.set_presence('available');
} */
var onLoginSuccess = function(){
$('.status').html("Connected and Logged In");
}
function onLoginFailure(){
alert('User could not be logged in');
}
function connectSuccess(){
$('.status').html("Connection Successful.");
}
function connectFailure(){
$('.status').html("Connection Failed!");
}
function onSetupNotification(){}
xmpp_client = new XMPPClient();
xmpp_client.connect('localhost',5222);
xmpp_client.onPresence = function(ntype, from) {
alert('Presence message' + ntype + ' From :' + from)
}
xmpp_client.onSocketConnect = function(domain, connectSuccess, connectFailure){
var domain = XMPPDOMAIN;
$('.status').html('Connected');
alert(user);
if(domain)
{
xmpp_client.connectServer(domain, connectSuccess, connectFailure);
xmpp_client.login(user, password, onLoginSuccess, onLoginFailure);
xmpp_client.set_presence('available');
}
}
function send_message(id, msg){
var j_id = id + '#' + 'siddharth-ravichandrans-macbook-pro.local';
alert('jid_id' + j_id);
var status = xmpp_client.msg(j_id, msg);
alert(status);
}
xmpp_client.onMessage = function(jid, username, text) {
alert('message-recieved');
if ( $('.discussion-area').length > 0 ){
$('.discussion-area').append('<div class=\'new-message\'>' + text + '</div>');
return false;
}
}
/* self.login = function(nick, pass, s, f) {
conn.onread = setUser;
success = s;
failure = f;
user = nick;
bare_jid = nick + "#" + domain;
full_jid = bare_jid + "/Orbited";
self.send(construct(LOGIN, [user, pass]));
}
self.set_presence = function(status, status_msg) {
self.send(EXT_PRESENCE[0] + full_jid + EXT_PRESENCE[1] + room_jid + EXT_PRESENCE[3] + status + EXT_PRESENCE[4] + status_msg + EXT_PRESENCE[5]);
}
*/
</script>
<% end %>
This is part of the xmpp.js which I got when I installed orbited and in order to test if my requests were actually reaching I added an alert in the login method as follows
...
...
self.login = function(nick, pass, s, f) {
conn.onread = setUser;
success = s;
failure = f;
user = nick;
bare_jid = nick + "#" + domain;
full_jid = bare_jid + "/Orbited";
self.send(construct(LOGIN, [user, pass]));
alert("bazingaa");
}
self.connectServer = function(d, s, f) {
success = s;
failure = f;
doma
...
...
Now I have no clue how this got my callbacks and would really appreciate some help on this.
Thanks
Actually I find that removing the xmpp_client.set_presence and moving it to the onLoginSuccess is what seems to have done the trick. The minute I add the set_presence method after the login method call the functionality fails in chrome. So why would that prevent it from invoking the callback on successful login?
var onLoginSuccess = function(){
$('.status').html("Connected and Logged In");
xmpp_client.set_presence('available');
}
xmpp_client.onSocketConnect = function(domain, connectSuccess, connectFailure){
var d = "";
$('.status').html('Connected');
xmpp_client.connectServer(d, connectSuccess, connectFailure);
xmpp_client.login(user, password, onLoginSuccess, onLoginFailure);
//xmpp_client.set_presence('available');
}
Help!
I think your problem is related to the Same Origin Policy for Javascript
https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
I'm sure the Safari/Chrome Web Inspector (with Javascript enabled) will verify this in the javascript console
Modern browsers (ie. not Internet Explorer!) get around this issue by implementing Cross-Origin Resource Sharing. But then your Javascript XMPP client library has to implement CORS too
http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
I'm not familiar with Orbited but I have done this type of browser XMPP connections using the Strophejs library and ejabberd's XMPP BOSH connection manager
To get around the Same Origin policy across all browsers you need to employ a proxy
http://flxhr.flensed.com/ (client-side proxy library)
If using apache you can employ a server-side proxy with the ProxyPass directive under the mod_proxy module

Categories