Server side actionscript: server to server stream republish with authentication - actionscript-3

I am trying to send a live stream from FMLE to a CDN, but passing through our FMS (installed locally); so the chain I have is:
FMLE => FMS => CDN
Now, publishing to the CDN is username/password protected. If I try to connect directly from FMLE to the CDN, FMLE opens a layer asking for credentials to "Connect to FMS" - I fill the form with username and password provided by the CDN, click on OK, and everithing works fine.
The problem comes when introducing the FMS: I created a simple application in FMS to republish the stream (simplified code below), and it works fine for CDN that don't ask for username/password, but I'm not able to figure out how to send credentials from the FMS application to the CDN.
Here the code I'm using (it's simplified, I'm putting here only the core code):
application.onPublish = function (oClient, oStream)
{
application.nc = new NetConnection (); // Creating new NetConnection
application.nc.connect (FMS_url); // Connecting to CDN
application.ns = new NetStream (application.nc); // Creating new NetStream
application.ns.setBufferTime (1); // Setting buffer time
application.ns.attach (oStream); // Attaching incoming streaming
application.ns.publish ("stream_name", "live"); // Publishing
}
More info:
We do need to pass through FMS, so "why don't you stream directly to the CDN ?" is not an option :-)
FMS URL and credentials are correct, it's not any typing error :-(
After application.nc.connect(), the onStatus event is fired with NetConnection.Connect.Success, but inmediately after that it is fired again with NetConnection.Connect.Closed (without any other info).
Following suggestions found on the web, I tryed things like
application.nc.connect (FMS_url);
or
application.nc.connect (FMS_url + "?username&password");
or adding
application.nc.addHeader ("Credentials", false, { userid: "username", password: "password" });
... but nothing seems to work, the result is always the same.
Any suggestion ? :-) Thank you in advance, best regards

Related

How to find out the availability status of a Web API from a Windows Store application

I have a Line-of-Business (LoB) Windows 8.1 Store application I developed for a client. The client side-loads it on several Windows 10 tablets. They use it in an environment where WiFi is spotty at best and they would like to get some sort of notification inside the app, regardless of what page they are on, notification that will let them know that they've lost connectivity to the network. I have created a method on my Web API that is not hitting the repository (database). Instead, it quickly returns some static information regarding my Web API, such as version, date and time of the invocation and some trademark stuff that I'm required to return. I thought of calling this method at precise intervals of time and when there's no response, assume that the Web API connectivity is lost. In my main page, the first one displayed when the application is started, I have the following stuff in the constructor of my view model:
_webApiStatusTimer = new DispatcherTimer();
_webApiStatusTimer.Tick += OnCheckWebApiStatusEvent;
_webApiStatusTimer.Interval = new TimeSpan(0, 0, 30);
_webApiStatusTimer.Start();
Then, the event handler is implemented like this:
private async void OnCheckWebApiStatusEvent(object sender, object e)
{
// stop the timer
_webApiStatusTimer.Stop();
// refresh the search
var webApiInfo = await _webApiClient.GetWebApiInfo();
// add all returned records in the list
if (webApiInfo == null)
{
var messageDialog = new MessageDialog(#"The application has lost connection with the back-end Web API!");
await messageDialog.ShowAsync();
// restart the timer
_webApiStatusTimer.Start();
}
}
When the Web API connection is lost, I get a nice popup message that informs me that the Web API is no longer available. The problem I have is that after a while, especially if I navigate away from the first page but not necessary, I get an UnauthorizedAccessException in my application.
I use the DispatcherTimer since my understanding is that this is compatible with
UI threads, but obviously, I still do something wrong. Anyone cares to set me on the right path?
Also, if you did something similar and found a much better approach, I'd love to hear about your solution.
Thanks in advance,
Eddie
First, If you are using Windows Store Apps, then you could possibly use a Background task to check poll for the status of the web api instead of putting this responsibility on your view model, its not the viewmodels concern
Second, if you are connecting from your Windows store app to your API then one successful authentication/ authorization for the first time, how and where do you store the token (assuming you are using token authentication). If you are (and ideally you should), is there a timer that you start which is set to the token expiration time? Is your local storage getting flushed somehow and loosing the aurthorization data?
Need more information.

AS3: SharedObject is not visible in Administration Console

I created a media server with 'Adobe Media Server Starter 5' on localhost and I am able to connect to it via an AS3 AIR Application. I can see the connection from my Application called 'SimpleServer' in the 'Adobe Media Server Administration Console' and I get a positive feedback about the connection:
Accepted a connection from IP:127.0.0.1, referrer: app:/SimpleServer.swf, pageurl:
I neither get a compile time nor a runtime error when trying to create a new SharedObject, I get no feedback at all. I am using the following code:
var shared:SharedObject = SharedObject.getRemote("HelloWorld", "rtmp://localhost/SimpleServer");
shared.addEventListener(SyncEvent.SYNC, syncEventHandler);
shared.connect(nc);
The NetConnection is created as followed:
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.connect("rtmp://localhost/SimpleServer");
nc.client = this;
I cannot see a SharedObject in 'View Applications' -> 'Shared Objects' and I get no feedback about the creation. It is like the object has never been created. I also tried to set properties on the SharedObject, with no effect:
shared.setProperty("test", false);
Is there a simple solution to this problem or do I have to configure advanced server stuff? Thank you in advance!
As Sunil asked in the comments, is syncEventHandler ever called when you run your code?
To partially answer your questions: No you don't need any specific server-side configuration to be able to retrieve a SharedObject on the client side. Simply make sure your connected to the server before performing any attempt at getting/connecting to a remote shared object.
See this answer for some more informations
Besides, a good practive when attempting to get a remote shared object is also to use the uri from your NetConnection instance:
var shared:SharedObject = SharedObject.getRemote("HelloWorld", nc.uri);

Flash As3 Number of people online

I have created a Jar that I want to fill with fireflies, depending on how many users are online.
I did a little digging and I found how to create a XMLSocket. It worked but I didn't know how to get the information how many people are online and also it required a CMD window to run all the time.
The second way I found was trough a PHP,MYSQL witch I have runing with my Apache server, but the tutorials and scripts I found did not work for me, for example. I did not create the required tables.
My question is what is the simplest way to find the current count of users online on your page/flash file? Is there a quick way to do it inside flash and not get involved with MYSQL or PHP?
No, there is not a simple way to only do it in Flash without using any external part (PHP, MySQL, Java, and more...). Remember that Flash is run locally, and thus needs to interact with PHP or similar to interact with the server to tell the server about the activity by the user and to ask the server about other users activities (number of users online).
If you only want to display the users online, I recommend the way that is shown in the example you posted. Simply update the database when activity has been seen by a user and count the user as offline when no activity has been seen for x minutes. There's no need to involve XMLSockets for this unless you want the users to interact with each other in any way.
If you want more than just displaying the users online, I recommend using XMLSockets in ActionScript and looking into PHP Sockets.
i dont think so, the flash player must need a way to "check" on the server the number of users who are online. the simplest would be to send a URLRequest (i hope i got the class name right) to a server script, which could be either a php or an aspx (or any server technology) script / page.
that server script should return the number of users the site has.
e.g.
var numberOfVisitors:Int = 0;
function onLoaded(e:Event):void {
numberOfVisitors = e.target.data;
// now print this 'numberOfVisitors' where you want to on the client
}
var numVisitors:URLLoader = new URLLoader();
numVisitors.addEventListener(Event.COMPLETE, onLoaded);
numVisitors.load(new URLRequest("num_users.php"));
the next part would be a php script (or any other server script) that keeps track of the number of users. that i think you should post as another SO question perhaps?
I got it to work, but I hat to link the php file not trough it's HTTP address, instead just the path relative to the .swf file (just myFile.php or path/myFile.php).
AS3 file:
NewRequest = new URLRequest("numOnline.php");
var numberOfVisitors:int = 10;
var NewRequest:URLRequest;
var UrlLoader:URLLoader;
UrlLoader = new URLLoader();
UrlLoader.dataFormat = URLLoaderDataFormat.TEXT;
UrlLoader.addEventListener(Event.COMPLETE, onLoaded);
UrlLoader.load(NewRequest);
function onLoaded(e:Event):void {
trace(e.target.data);
numberOfVisitors = int(e.target.data);
}
I convert the text As3 receives to int, because i don't know yet how to send veria
php files
main PHP file (the file that as3 connects to):
<?php
include_once 'config.php'; //This file would contain the variables needed to connect to the database with $link, below
include_once 'functions.php'; //We include the functions we have created
$database = "online";
$link = mysql_connect($server, $db_user, $db_pass)or die ("Could not connect to mysql because ".mysql_error());
mysql_select_db($database)or die ("Could not select database because ".mysql_error());
usersOnline(5); //We call the usersOnline function with a time span of 5 minutes
showUsersOnline(1); //Show the number of users online, and the list of users
mysql_close($link);
?>
the function file sends the number of Visiters Online with echo $count;
Yes, you can do it without a database (MYSQL) and PHP; BUT you will still need a (Media) Server.
I wouldn't suggest the following if your "only" purpose is to count the connecting clients, but if you have the reasons and have access to a Flash Media Server, you can try the following:
On Server Side:
Create an application (folder) on FMS, create the main.asc file inside that folder.
Inside the main.asc; create a (remote) SharedObject (server-side) (e.g.: users_so)
Watch for connecting clients on application.onConnect event. Add each connecting client to that SharedObject inside this handler.
Also watch for disconnecting clients on application.onDisconnect event. Remove each disconnecting client from the SharedObject inside this handler.
On Client Side:
Connect each Flash client to FMS (with your new app-folder path in the URI) when the application loads in the browser.
Watch for the NetStatusEvent.NET_STATUS event and "NetConnection.Connect.Success" code. When connected; create a SharedObject (client-side) and get the remote from the server.
Add the SyncEvent.SYNC event listener to the SharedObject. This will sync with each Flash client when a user connects or disconnects from the server.
Inside the sync event handler, get and count the users from the event response.
Display the count on your Flash client.
See Server-Side ActionScript Language Reference for Flash Media Server 4.5, especially the Application Class.
Also useful: Flash Media Server Developer Center
Hope this helps.

HTML5 Offline / Online App

Im building a small todo app in html5. Works fine so far but i have a problem: If the user visits http://www.mydomain.com/ he is prompted to login. If he is logged in on / a different template is served -> my main application template. Plus a cookie is set for session handling.
Now he can add/delete/edit his todos. While he is online the todos are saved on the server.
I also added a cache manifest for my site and use local storage to save his todos when he's offline. This works fine so far.
My Problem: If the user is online and logs himself out of the site, and the server isn't serving the main application template anymore, the browser uses the offline version of the site. But he should only use it if the browser is offline, not when the server is sending another template on the same path.
Someone a hint for me? Thanks in advance!
Use this function to get the cookie that is stored on your client machine. In case it returns null then that means the user is logged out. This should be done every time the page is loaded. You could also redirect the user to the login page.
var function getCookie(c_name)
{
var i,x,y,ARRcookies=document.cookie.split(";");
for (i=0;i<ARRcookies.length;i++)
{
x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
x=x.replace(/^\s+|\s+$/g,"");
if (x==c_name)
{
return unescape(y);
}
}
}
var cookie = getCookie("myDomainAuthenticationCookie");
if(cookie == null)
{
window.location.href = "/myDomain.com/Accounts/Login"
}

Execute exe-file from html-page?

I want to launch a local exe-file (without saving it to another location first) upon clicking on a link on a local html file.
It either needs to work in IE, Firefox, Chrome or Opera, I don't care. It's just for a presentation tomorrow.
It's simply not possible. If it was, it would be considered a security flaw and fixed. On Firefox within hours, on IE within some months.
UPDATE: You could try registering your custom protocol: http://openwinforms.com/run_exe_from_javascript.html
But I believe the browser will still prompt you whether you want to run the app.
I want to share my experience.
The accepted response says that it is not possible but it is quite possible indirectly.
If you want to execute an exe on a pc, it means that you have acces on this pc and you can install your exe on that machine.
In my case, I had to take a 3D scan from a 3D scanner via a web application. It seemed impossible at the beginning.
After lots of research, I found that we can send socket messages via javascript.
It means that if we had an application which listens a specific port, it can communicate with a website.
Let's explain how I did this.
In my web application, I created a javascript method like this :
function openCapron3DScanner(foot) {
$("#div-wait").show();
//Creates a web socket pointed to local and the port 21000
var ws = new WebSocket("ws://127.0.0.1:21000");
ws.onopen = function () {
//Sends the socket message to the application which listens the port 21000
ws.send(foot + "-" + #ProjectHelper.CurrentProject.Proj_ID);
};
ws.onerror = function myfunction() {
$("#div-wait").hide();
alert("Erreur connection scanner.");
}
ws.onmessage = function (evt) {
//Receives the message and do something...
var received_msg = evt.data;
if (received_msg == "ErrorScan") {
alert("Erreur scan.");
}
else {
refreshCurrentProject();
}
};
ws.onclose = function () {
$("#div-wait").hide();
};
};
And I created a windows forms application who listens the localhost and port 21000.
This application is hidden, only shown in icon tray.
The only thing to do is to add the application on windows startup via code on the first load to assure that the next restart of windows it will be executed and listen the port.
private static WebSocketServer wsServer;
static WebSocketSession LastSession;
private void Form1_Load(object sender, EventArgs e)
{
wsServer = new WebSocketServer();
int port = 21000;
wsServer.Setup(port);
wsServer.NewMessageReceived += WsServer_NewMessageReceived;
wsServer.Start();
}
private static void WsServer_NewMessageReceived(WebSocketSession session, string value)
{
if (value.StartsWith("ScanComplete-"))
{
//If the scan is ok, uploads the result to the server via a webservice and updates the database.
UploadImage(value);
//Sends a confirmation answer to the web page to make it refresh itself and show the result.
if (LastMacSession != null)
LastMacSession.Send("ScanComplete");
}
else if (value == "ErrorScan")
{
//If the C++ application sends an error message
if (LastMacSession != null)
LastMacSession.Send("ErrorScan");
}
else//call the 3D Scanner from the web page
{
LastSession = session;//Keeps in memory the last session to be able to answer via a socket message
//Calls the C++ exe with parameters to save the scan in the related folder.
//In could be don in this same application if I had a solution to consume the scanner in C#.
var proc = System.Diagnostics.Process.Start(#"C:\Program Files\MyProjectFolder\MyScannerAppC++.exe", projectID + " " + param);
}
}
I hope it will help.
Use System.Diagnostics.Process.Start() method.
protected void LinkButton1_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("notepad.exe");
}
You'll have to use C#, but since that's on your post, it should work. You'll also need the full path, if the file is not in your environment path that's loaded in memory.
For a 'regular link' you'd still need to place this in an ASPX page.....
Click me
We're getting really fugly now though.
You can't run an exe file on a website. (First, if it's a Linux server, exe files won't run on it and second, if you're on a Windows server, your host would kill the program immediately. And probably terminate your account.)
That link (assuming it was Play Now!) will just allow your user to download the file. (C:\Program Files\World of Warcraft\ exists on your computer, but it doesn't exist on the web server.)
You could setup a custom protocol on your local OS, if it's Windows, in regedit.
Check out this and this.
Then you create a simple HTML page, and place a link, something like this :
Start!
Given that you registered your custom "presentation" protocol, and configured it correctly in the registry, the application should launch when you click that link.