Flash As3 Number of people online - actionscript-3

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.

Related

Server side actionscript: server to server stream republish with authentication

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

node.js - repeatedly updating webpage from mysql database

I am trying to create a node.js app to automatically update a webpage every few seconds with new data from a mysql database. I have followed the information on this site: http://www.gianlucaguarini.com/blog/push-notification-server-streaming-on-a-mysql-database/
The code on this site does indeed work, but upon further testing it keeps running the "handler" function and therefore executing the readFile function for each row of the database processed.
I am in the process of learning node.js, but cannot understand why the handler function keeps getting called. I would only like it to get called once per connection. Constantly reading the index.html file like this seems very ineffecient.
The reason that I know the handler function keeps getting called is that I placed a console.log("Hello"); statement in the handler function and it keeps outputting that line to the console.
Do you provide the image URLs that the client.html is looking for? Here's what I think is happening:
The client connects to your server via Socket.IO and retrieves the user information (user_name, user_description, and user_img). The client then immediately tries to load an image using the user_img URL. The author's server code however, doesn't appear to support serving these pictures. Instead it just returns the same client.html file for every request. This would be why it appears to be calling handler over and over again - it's trying to load a picture for every user.
I would recommend using the express module in node to serve static files instead of trying to do it by hand. Your code would look something like this:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.use(app.static(__dirname + "/public"));
That essentially says to serve any static files they request from the public folder. In that folder you will put client.html as well as the user photos.

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);

NetStream.send not working with NetGroup in RTMFP

We are running a Cumulus server to do a live voice and text chat.
The setting is that each client can post data to each other client in the same NetGroup via group.post(). Unfortunately, that function is extremely slow (half a second delay, at least), so we switched to using NetStream.send to call functions on other clients, passing the data through that. This works almost instantly.
However, we are now trying to build separate chat rooms, using different NetGroups. But when doing so, NetStream.send() doesn't work anymore, the functions are never called on the other clients, and no voice data is transferred. Basically, the whole publishing NetStream seems to be not working any more.
We have the following setup to establish a NetGroup and a publishing stream on each client:
var gspec:GroupSpecifier = new GroupSpecifier("Group1");
gspec.multicastEnabled = true;
gspec.postingEnabled = true;
gspec.serverChannelEnabled = true;
gspec.objectReplicationEnabled = true;
gspec.routingEnabled = true;
_group = new NetGroup(_netConnection, gspec.groupspecWithAuthorizations());
_group.addEventListener(NetStatusEvent.NET_STATUS, handleNetGroupStatus);
_sendStream = new NetStream(_netConnection, gspec.groupspecWithAuthorizations());
_sendStream.addEventListener(NetStatusEvent.NET_STATUS, handleNetStreamStatus);
_sendStream.client = this;
_sendStream.attachAudio(_mic);
_sendStream.publish("media");
And the following code is used to listen to the "media" stream:
case "NetGroup.Neighbor.Connect":
var netStream :NetStream = new NetStream(_netConnection, p_netStatusEvent.info.peerID);
netStream.addEventListener(NetStatusEvent.NET_STATUS, handleNetStreamStatus);
netStream.client = this;
netStream.play("media");
break;
The NetGroup connection itself works, and "NetGroup.Neighbor.Connect" is called on each client when a neighbor connects. But the _sendStream itself simply doesn't work. No data is received, no function called.
It does work when the publishing NetStream is constructed in the following way:
_sendStream = new NetStream(_netConnection, NetStream.DIRECT_CONNECTIONS);
However, we only want the NetStream to send to a single NetGroup, and according to the Adobe Documentation, using gspec.groupspecWithAuthorizations() in the constructor should allow exactly that.
Are we missing something here?
I found the answer:
You also have to make the receiving NetStream listen to gspec.groupspecWithAuthorizations() instead of p_netStatusEvent.info.peerID.
This does work. Unfortunately, this makes voice chat impossible, as it is incredibly slow (as slow as NetGroup.post()) and introduces many sound artifacts.
So, we'll have to find another solution for different chat rooms...

AS3 Loading XML from a different domain

I am trying to load an xml file from wikipedia into my flash movie.
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, tweetLoaded);
loader.load(new URLRequest("http://en.wikipedia.org/w/api.php?action=query&rvprop=content&format=xml&pageids="+subNum));
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorFunction);
This works fine when the flash file is run locally but when I upload to my domain it does not seem to work. I have read elsewhere that the cross domain rule does not apply to XML files only to images and other media. Is this true? If not is there a work around so that I can load in XML files from domains other than the one the swf is hosted on?
thanks
EDIT:
Okay I am really confused, my program queries both Bing API and the media wiki API. The Bing api call works fine, I can retrieve the XML search results back from it fine. But the wikipedia call does not work (online). I have tried listening for the Security_Error on the wikipedia call but it does not fire.
Does anyone have any ideas? Losing it a bit.
Thanks so much for you help. In the end i used http://pipes.yahoo.com
I created a pipe that took in an ID number then spat out a JSON object with the title of the corresponding wikipedia page.
which you can use here http://pipes.yahoo.com/wikibyid
For anyone else doing this you need to make sure you access the pipe from the yahoo api URL
http://pipes.yahooapis.com/
as this domain has the crossdomain.xml file.
A workaround is setting up a proxy with some server side language, so your swf loads data from your domain. This proxy forwards the request to the real host and returns the response to the swf. From the flash side, this works transparently.
You could make your proxy more or less sofisticated, but it could be as simple as (in php):
echo file_get_contents($_GET['target_url']);
This is just to give you an idea, you might want to validate the target_url parameter.
Have your swf call this php script and pass target_url as a parameter. Something like this:
var url:String = "proxy.php";
var paramVal:String = encodeURIComponent("http://en.wikipedia.org/w/api.php?action=query&rvprop=content&format=xml&pageids="+subNum);
url += "?target_url=" + paramVal;
loader.load(new URLRequest(url));
Note that for php this will require allowing fopen for urls (similar permissions might be neccesary for other server side technologies). Also, keep in mind this will affect your server bandwith consumption.
PS
Bing works because they have a crossdomain policy file in place to allow access to swfs from other domains.
http://api.bing.net/crossdomain.xml
Wikipedia doesn't have a crossdomain policy file that grants you access from other domains, so you cannot connect directly from your swf.