Face to face video chat using openTok (tokbox) - javascript

I build a kind of a social network where the users can chat with each other.
Only private chats, not rooms or groups or anything like this.
I want to to add a feature to the chat - video chat.
And I find openTok (tokbox).
I read alot from thier manual but I can't make it work.
I started in something simple.
I opend in two different computers url with this code:
<html>
<head>
<script src="http://static.opentok.com/webrtc/v2.0/js/TB.min.js" ></script>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<script type="text/javascript">
var apiKey = **myApiKey**;
var sessionId = **sessionId **;
var token = **token**;
function sessionConnectedHandler (event) {
session.publish( publisher );
subscribeToStreams(event.streams);
}
function subscribeToStreams(streams) {
for (var i = 0; i < streams.length; i++) {
var stream = streams[i];
if (stream.connection.connectionId
!= session.connection.connectionId) {
session.subscribe(stream);
}
}
}
function streamCreatedHandler(event) {
subscribeToStreams(event.streams);
}
var publisher = TB.initPublisher(apiKey);
var session = TB.initSession(sessionId);
session.connect(apiKey, token);
session.addEventListener("sessionConnected",
sessionConnectedHandler);
session.addEventListener("streamCreated",
streamCreatedHandler);
</script>
</head>
<body>
</body>
</html>
Of course I changed myApiKey, sessionId, token to my details from my account.
The problem is that In every page I can see myself, buy the partner window doesn't stop loading...
What can I do?
Thanks

In your sessionConnectedHandler(), you have to remove publisher parameter, then it works fine... Somewhat look like this:
function sessionConnectedHandler(event) {
subscribeToStreams(event.streams);
session.publish();
}

Related

Recording State of iframe(url) from within an Office Add-in

So I am developing an office add in which will essentially contain an iframe which will be running an application we own.
The problem is, I want to contantly record the url of the iframe so that i can save this to the addin state, aloowing us to use that information to load the iframe to the correct url each time the addin is reopened.
I cant figure out a way to output the url from within the iframe each time it changes? here is a sample of what i have, this doesnt contain the application just a couple of sample pages:
Home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title></title>
<script src="../Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<script src="../Scripts/FabricUI/MessageBanner.js" type="text/javascript"></script>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<link href="Home.css" rel="stylesheet" type="text/css" />
<script src="Home.js" type="text/javascript"></script>
<!-- For the Office UI Fabric, go to https://aka.ms/office-ui-fabric to learn more. -->
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.1.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.1.0/fabric.components.min.css">
</head>
<body>
</body>
</html>
Home.js
(function () {
"use strict";
// The initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
var iframew = document.createElement('iframe');
iframew.src = '../SecondPage/SecondPage.html';
iframew.id = 'iframe1';
iframew.onload = iframeLoaded(this.contentWindow.location.href);
document.body.appendChild(iframew);
});
};
// Helper function for displaying notifications
function iframeLoaded(location) {
console.log("log", location);
}
})();
Cant understand why people are downvoting this question, it was a genuine issue
Anyway, for anyone interested I solved this by attaching a a function after the iframe loads which outputs the url of the iframe at set interval periods
var iframew = document.createElement('iframe');
iframew.id = 'iframe1';
var baseUrl = '#YOUR BASE URL#';
let openUrl = getProperty('openurl');
if (!openUrl) {
console.log('No saved url');
iframew.src = baseUrl;
}
else {
console.log('saved url');
console.log(openUrl);
iframew.src = openUrl;
}
//when iframe loads attach function to save at interval
iframew.addEventListener('load', function () { setInterval(function () { iframeLoaded(iframew.contentWindow.location.hash, iframew.contentWindow.location.href); }, 4000); });
document.body.appendChild(iframew);
here is the iframeLoaded Function which also does some manipulation of the url and calles another function which saves the url to the doocument settings of the add-in:
function iframeLoaded(hash, location) {
//if not in an analysis dont save
if (hash.indexOf('#/dataset/') !== -1 ) {
console.log("Same url")
return
}
//remove # from hash
hash = hash.substr(1);
//concatenate base and hash
let newUrl = baseUrl + hash;
console.log(hash)
console.log(newUrl);
//save
if (Office.context.document.settings) {
saveProperty('openurl', newUrl);
}
}

Silence net::ERR_CONNECTION_REFUSED

Connecting to a non-existent web socket server results in loud errors being logged to the console, usually to the tune of ... net::ERR_CONNECTION_REFUSED.
Anyone have an idea for a hackaround to silence this output? XMLHttpRequest won't work since it yields the same verbose error output if the server is not reachable.
The goal here is to test if the server is available, if it is then connect to it, otherwise use a fallback, and to do this without spamming the console with error output.
Chrome itself is emitting these messages, and there is no way to block them. This is a function of how chrome was built; whenever a ResourceFetcher object attempts to fetch a resource, its response is passed back to its context, and if there's an error, the browser prints it to the console - see here.
Similar question can be found here.
If you'd like, you can use a chrome console filter as this question discusses to block these errors in your console, but there is no way to programmatically block the messages.
I don't know why do you want to prevent this error output. I guess you just want to get rid of them when debugging. So I provide a work around here may be just useful for debugging.
Live demo: http://blackmiaool.com/soa/43012334/boot.html
How to use it?
Open the demo page, click the "boot" button, it will open a new tab. Click the "test" button in the new tab and check the result below. If you want to get a positive result, change the url to wss://echo.websocket.org.
Why?
By using post message, we can make browser tabs communicate with each other. So we can move those error output to a tab that we don't concern.
P.S. You can refresh the target page freely without loosing the connection between it and boot page.
P.P.S You can also use storage event to achieve this.
boot.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>boot page</title>
</head>
<body>
<button onclick="boot()">boot</button>
<p>BTW, you can boot the page without the button if you are willing to allow the "pop-up"</p>
<script>
var targetWindow;
function init() {
targetWindow
}
function boot() {
targetWindow = window.open("target.html");
}
boot();
window.addEventListener('message', function(e) {
var msg = e.data;
var {
action,
url,
origin,
} = msg;
if (action === "testUrl") {
let ws = new WebSocket(url);
ws.addEventListener("error", function() {
targetWindow.postMessage({
action: "urlResult",
url,
data: false,
}, origin);
ws.close();
});
ws.addEventListener("open", function() {
targetWindow.postMessage({
action: "urlResult",
url,
data: true,
}, origin);
ws.close();
});
}
});
</script>
</body>
</html>
target.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>target page</title>
</head>
<body>
<h4>input the url you want to test:</h4>
<textarea type="text" id="input" style="width:300px;height:100px;">
</textarea>
<br>
<div>try <span style="color:red">wss://echo.websocket.org</span> for success result(may be slow)</div>
<button onclick="test()">test</button>
<div id="output"></div>
<script>
var origin = location.origin;
var testUrl = origin.replace(/^https?/, "ws") + "/abcdef"; //not available of course
document.querySelector("#input").value = testUrl;
function output(val) {
document.querySelector("#output").textContent = val;
}
function test() {
if (window.opener) {
window.opener.postMessage({
action: "testUrl",
url: document.querySelector("#input").value,
origin,
}, origin);
} else {
alert("opener is not available");
}
}
window.addEventListener('message', function(e) {
var msg = e.data;
if (msg.action === "urlResult") {
output(`test ${msg.url} result: ${msg.data}`);
}
});
</script>
</body>
</html>

Unable to make tracking pixel send data to api

I'm trying to use this library to implement a tracking pixel.
I'm testing in my localhost machine with Apache.
I have a index.html page at htdocs/openpixel/index.html
with the following content:
<html>
<head>
Test Pixel
</head>
<body>
Test Pixel
<!-- Start Open Pixel Snippet -->
<script>
!function(e,t,n,p,o,i,a,s,c){e[o]||(a=e[o]=function(){a.process?a.process.apply(a,arguments):a.queue.push(arguments)},a.queue=[],a.t=1*new Date,s=t.createElement(n),s.async=1,s.src=p+"?t="+Math.ceil(new Date/i)*i,c=t.getElementsByTagName(n)[0],c.parentNode.insertBefore(s,c))}(window,document,"script","http://127.0.0.1/openpixel/v1/openpixel.js","opix",864e5),opix("init","ID-123"),opix("event","pageload");
</script>
<!-- End Open Pixel Snippet -->
</body>
</html>
This is openpixel.js, where it should send the data to an endpoint
...
window.onload = function () {
var aTags = document.getElementsByTagName('a');
for (var i = 0, l = aTags.length; i < l; i++) {
aTags[i].onclick = function (e) {
if (Url.externalHost(this)) {
Config.externalHost = { link: this.href, time: now() };
}
}.bind(aTags[i]);
}
};
}(window, document, window["opix"], "opix", "http://localhost:3000/pixel_data", 1));
...
I also created an endpoint api in Node.JS to receive this pixel. When I test it with a browser get resquest it is responding.
app.get('/pixel_data', function(req, res) {
console.log(req.query);
});
The problem is when I access pixel.html, the endpoint /pixel_data is logging nothing. I'm trying to understand the problem here.
You're Node.js server is not able to see the query string because it looks like your server is on localhost:3000 and you are sending a request to 127.0.0.1/openpixel/v1/openpixel.js.
Change your pixel tag to request localhost:3000 by changing http://127.0.0.1/openpixel/v1/openpixel.js to http://localhost:3000/pixel_data.

How do I create chat rooms in Firechat?

I am using Firechat and I am able to successfully initiate the chat window. I am using Firebase custom authentication and I can login without any problem. However, I now try to create a new chat room and then enter it. Based on the Firechat documentation I did the following:
<!doctype html>
<html>
<head>
<title>Test</title>
<meta charset="UTF-8" />
<script src='https://cdn.firebase.com/js/client/2.0.2/firebase.js'></script>
<link rel='stylesheet' href='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.css' />
<script src='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.js'></script>
</head>
<body>
<script type='text/javascript'>
var fireBase = new Firebase("https://XXXXXXXXX.firebaseio.com/");
function initChat(authData) {
var Firechat = new FirechatUI(fireBase, document.getElementById('firechat'));
Firechat.setUser(authData.uid, "Username");
Firechat.createRoom("Test chat room", "public");
}
fireBase.authWithCustomToken("UNIQUE_TOKEN", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Login successful", authData);
initChat(authData);
}
});
</script>
<div id='firechat'>
</div>
</body>
</html>
In the javascript console I can see that login is successful:
Login successful Object { auth: Object, expires: XXXXXXXXX, token: "XXXXXXXX…", uid: "XXXXXX", provider: "custom" }
But the createRoom function is not found:
TypeError: Firechat.createRoom is not a function
Any idea what is going wrong here?
From the docs:
Firechat.createRoom(roomName, roomType, callback(roomId))
Creates a new room with the given name (string) and type (string - public or private) and invokes the callback with the room ID on completion.
It would seem that you do not have a callback.
Firechat.prototype.createRoom = function(roomName, roomType, callback) {
var self = this,
newRoomRef = this._roomRef.push();
var newRoom = {
id: newRoomRef.name(),
name: roomName,
type: roomType || 'public',
createdByUserId: this._userId,
createdAt: Firebase.ServerValue.TIMESTAMP
};
if (roomType === 'private') {
newRoom.authorizedUsers = {};
newRoom.authorizedUsers[this._userId] = true;
}
newRoomRef.set(newRoom, function(error) {
if (!error) {
self.enterRoom(newRoomRef.name());
}
if (callback) {
callback(newRoomRef.name());
}
});
};
Source: https://firechat.firebaseapp.com/docs/firechat.html
So it turns out that there are two classes (is that the right word) used in the Firechat javascript plugin:
var chat = new FirechatUI
var chat = new Firechat
Because they seem so similar I did not notice the difference. Nowhere in the documentation have I been able to find details of the FirechatUI instance (even though this code is recommended on the github readme).
So anyway, the thing is that new FirechatUI loads the actual UI for the chat. new Firechat loads the API that allows you to talk to the chat plugin (but NOT to the UI). This is an important difference. The documentation found here only relates to the API so if you initiate a new Firechat instance. However, the trick is to get the UI up and running and then interact with it directly (doing things like creating new rooms or entering rooms). I have honestly not found out how to do this the official/recommended way. The only thing I've been able to come up with is a hack. It's ugly, but it works. The code below includes functionality to create a new chat room (using Firechat) and to open a particular chatroom in the UI (that bit is hacked as I couldn't find a way to interact with the UI directly).
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
<!-- jQuery -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script>
<!-- Firebase -->
<script src='https://cdn.firebase.com/js/client/2.1.0/firebase.js'></script>
<!-- Firechat -->
<link rel='stylesheet' href='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.css' />
<script src='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.js'></script>
<!-- This plugin here: https://gist.github.com/buu700/4200601 -->
<script type="text/javascript" src="js/arrive.js"></script>
<style type="text/css">
#firechat{width:400px}
</style>
</head>
<body>
<h1>Test</h1>
<script type='text/javascript'>
var fireBase = new Firebase("https://XXXXXX.firebaseio.com/");
function roomChatSetup(authData) {
var chat = new Firechat(fireBase);
chat.setUser(authData.uid, "My User Name", function(user) {
console.log("Creating chatroom...");
chat.createRoom("New Chatroom Name", "public", function(roomId) {
console.log("Created room "+roomId);
});
$("#firechat").html("<div class='alert alert-success'>Your chatroom has been set up. Refresh to view</div>");
});
}
function initChat(authData) {
var chatUI = new FirechatUI(fireBase, document.getElementById('firechat'));
chatUI.setUser(authData.uid, "My User Name");
console.log("Simulating clicks...");
$("#firechat-tab-content div.tab-pane").waitUntilExists(function(){
console.log("Close all other tabs by simulating clicking the X button");
$("#firechat-tab-content div.tab-pane:not(#XXXXXXXXX) a.close").click(); // XXXXX should have the chatroom name of the one you want to open
});
$("#firechat-btn-rooms").waitUntilExists(function(){
$("#firechat-btn-rooms").click();
console.log("Open submenu to load all possible rooms");
});
$("li[data-room-id='XXXXXXXXXXXXX']").waitUntilExists(function(){
$("li[data-room-id='XXXXXXXXXX'] a").click();
console.log("Simulating clicking on chatroom XXXXXXXXXXXXXX");
});
}
fireBase.authWithCustomToken("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Login successful", authData);
// Here you can use a programming language to decide. If you already have a
// chatroom, run initChat. If you don't, run createRoom. I haven't been
// able to run them both at the same time.
initChat(authData);
// or:
roomChatSetup(authData);
}
});
</script>
<div id="firechat"></div>
</body>
</html>
The FirechatUI object is separate from the Firechat object. FirechatUI does not have the same methods that Firechat does.
In order to get the associated Firechat object from a FirechatUI object you can do the following:
let chatUI = new FirechatUI(chatRef, document.getElementById("firechat-wrapper"));
let chat = chatUI._chat;
You can then do any normal Firechat operations without any issues.
chat.setUser(user.uid, firstName, function(user) {
chat.resumeSession();
});
Please keep in mind that the _chat element is not really supposed to be used (as you can tell from the naming convention), but since FirechatUI does not properly expose enough functionality this is probably the cleanest way to do it.

Play Framework 2.1 websockets in Chrome

I can't seem to get websocket communication to work in the Play Framework version 2.1.
I created a simple test that does nothing but send messages back and forth with a push of a button. All the code for it is below. But nothing shows up except for the button.
Has anybody seen this problem or can someone tell me what I may be doing wrong in the code below?
I am using the latest version of Chrome.
Here is my simple setup.
In Application.java
public static Result index() {
return ok(index.render());
}
public static WebSocket<String> sockHandler() {
return new WebSocket<String>() {
// called when the websocket is established
public void onReady(WebSocket.In<String> in,
WebSocket.Out<String> out) {
// register a callback for processing instream events
in.onMessage(new Callback<String>() {
public void invoke(String event) {
System.out.println(event);
}
});
// write out a greeting
out.write("I'm contacting you regarding your recent websocket.");
}
};
}
In Routes File
GET / controllers.Application.index()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
GET /greeter controllers.Application.sockHandler()
In Index.Scala.html
#main(null) {
<div class="greeting"></div>
<button class="send">Send</button>
<script type="text/javascript" charset="utf-8">
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var sock = new WS("#routes.Application.sockHandler()")
sock.onmessage = function(event) {
$('.greeting').append(event.data)
}
$('button.send').click(function() {
sock.send("I'm sending a message now.")
});
})
</script>
}
In Main.scala.html
#(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>#title</title>
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.at("images/favicon.png")">
<script src="#routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
</head>
<body>
#content
</body>
The problem is in
var sock = new WS("#routes.Application.sockHandler()")
you have to specify the protocol and the complete url in the format: ws://localhost:9000/greeter.
Check this question to do it in javascript: How to construct a WebSocket URI relative to the page URI?
you can use a Route's webSocketURL() method to retrieve a url that can be passed to a WebSocket's constructor. Here's an example from Play's websocket-chat sample code:
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var chatSocket = new WS("#routes.Application.chat(username).webSocketURL()")
var sendMessage = function() {
chatSocket.send(JSON.stringify(
{text: $("#talk").val()}
))
$("#talk").val('')
}
// ...
So in your code you can use something like
var sock = new WS("#routes.Application.sockHandler().webSocketURL()");
Personally I don't like intermingling interpolated code with JS, since I think that any code executing on the client should only be concerned with the state of the client, and not the server (not to mention it makes refactoring the script out into an external file impossible), so I tend to do something like this:
<div class="container app-container"
data-ws-uri="#routes.Application.WSUri.webSocketURL()">
.......
</div>
Then in my JS I can just do something like
var sock = new WS(document.querySelector(".app-container").dataset.wsUri);
// ....

Categories