Implementation of RTMFP for p2p applications


#1

I’m close friend with the authors of MonaServer and the librtmfp library. I’m not aware if the NetConnection implementation exists already with RedTamarin and I would like to know if there is a possibility to implement RTMFP in RedTamarin.

Best Regards


#2

Hi, so I don’t have a lot of time but I gonna try to summarise the situation

when we talk about NetConnection and RTMFP in relation to Redtamarin
here the few things to take into account

  • Flash Player and AIR have a client implementation
    Redtamarin need to replicate that client implementation
    but also need to provide a server implementation (kind of like MonaServer)
  • it is mainly connection over sockets but using a specific communication protocols
    that is: RTMP, RTMPE, RTMPT, RTMPTE, RTMS, RTMFP
    see NetConnection.protocol
  • even before trying to implement those or one of those we need few other things to be working first

so those other things that need to be working first, here the list in order of priority

  • an event loop
  • an event system (that work with that event loop)
  • Socket class
  • ServerSocket class
  • SecureSocket class that can use SSL/TLS
  • being able to serialize/deserialize AMF packets, AMF0 and AMF3
  • and HTTP library that can parse/generate HTTP Requests/Responses
  • other libraries to parse RTMP, and other protocols

currently in Redtamarin

  • we figured out the event loop and event system
    it still need some work, especially to be able to send/receive events between workers
  • and we are in the middle of implementing core API classes in flash.net and flash.filesystem
  • in short we will have a flash.net::Socket class that will work the same as Flash or AIR
    but we will also have a shell.network::TCPSocket that will work slightly differently,
    this in order to implement navigateToURL() and sendToURL() also in flash.net package
  • internally we need URL and HTTP libraries also to make things sendToURL() works (basically an HTTP POST reusing sockets)
  • the source code of AVMplus already provide an AMF3 serializer/deserializer
    but we still need to work on it to also support AMF0 as some protocols negociate a connection first in AMF0 and then transition to AMF3

let’s say you will probably have all that in v0.4.2

then in a next iteration we plan to implement LocalConnection and at the same time shared memory low level functions (POSIX and System V)

  • the goal of LocalConnection is to be able to communicate between Redtamarin and Flash/AIR
  • because LocalConnection use shared memory but in a very preservative way
    and because we have bigger needs for other projects we will also implements some SharedMemory class that can do a lot , for example
    • be able to reserve a block of memory
    • send/receive data from/to it with semaphore
    • be able to serialize/deserialize to it with AMF3
    • goal be able to build your own little Redis/MemCached supporting AS3 types

in yet another iteration we will look into implementing SSL/TLS, probably linking to openSSL library, and that will allow us to implement something like SecureSocket class and other encryption utilities.

In parallel of all that you will see popup few AS3 libraries reusing those Redtamarin native API
things like: httplib , ftplib, etc. that will allow to implement your own HTTP client or server, and hopefully will also be able to evolve to support HTTPS.

After these kind of libraries, you will see popup something related to AMF, think AMFPHP but implemented in AS3/Redtamarin.

And after all that, we will then finally be able to start to work

  • on NetConnection eg.

    The NetConnection class creates a two-way connection between a client and a server.

  • on NetStream

    The NetStream class opens a one-way streaming channel over a NetConnection.

  • on RTMP and RTMFP
    between the RFC and other implementations build our own libraries that can talk with those specific protocols

With that then the same way we can have an “AMF server” that works like AMFPHP,
we then be able to have a “RTMFP server” that works like MonaServer or other similar servers


So yeah it looks a bit complicated like that but we are forced to do the basic steps before being able to implement NetConnection and/or RTFMP properly

for example: if you don’t have an event system well it will be difficult, if you don’t have solid socket implementations, it gonna be very difficult, and same if you don’t a solid HTTP library, it does not help, etc.

we don’t want to rush those


But while all that is evolving, and yeah probably slowly, we also add core stuff that will help later

for example

that Run-Time Compiler gonna allow us and others to do very magic things in Redtamarin

so for example, when it comes to sockets and being able to do things asynchronously (because you don’t want your main event loop to choke) it will be very useful to be able to write dynamically small AS3 code that will be directly compiled and ran into a worker (so running on a separate thread)

it will allow to do Promise, perhaps even coroutines to a certain extent
without the need to plan it in advance and pre-compile some codes to .abc
all dynamic, all in memory :slight_smile:

Same for other stuff like the shared memory, it will not have the limitation of 40KB that you have in LocalConnection, and for servers it will allow to “talk over memory between different processes” in nanoseconds instead of milliseconds.

see LocalConnection.send()

There is a 40 kilobyte limit to the amount of data you can pass as parameters to this command. If send() throws an ArgumentError but your syntax is correct, try dividing the send() requests into multiple commands, each with less than 40K of data.


So yeah we could take shortcuts and focus only on RTMFP and only build little essentials to get there faster, but that’s not the strategy we decided to take.

But RTMFP is definitively on our radar, and yes it is possible to implement it,
we just need solid core components (either native or libraries) and that will take time.


#3

To save you some time the librtmfp library has everything concerning RTMP and RTMFP with UDP. Why don’t you make a wrapper around that library and make the classes accessible with a C++ and AS3 bridge and compile it in redtamarin? Is that idea make any sense ?


#4

Concerning RTMFP server I made an ANE which has integrated an RTMFP server that I use with my Adobe AIR App for p2p features.


#5

you could do that but then that the shortcuts I was talking about

to give an example, you can implement SecureSocket
using the curl library, but then you depends on the curl library

when you implement the core elements like socket, TLS/SSL library, HTTP library etc.
then you can write your own curl

I don’t know librtmfp, depending on how this library is done
there are some thing you could do and other things you could not do
for ex: integrating events, doing things synchronously or asynchronously, etc.


#6

I think you should contact the authors they built it in a amazing way taking into consideration the Flash Player with all the specs. I think you might find 80% of what you are looking for in that library.


#7

maybe but you are missing something

if the librtmfp works on its own then what? I don’t need to implement Socket or SecureSocket in Redtamarin anymore?

no, I still have to implement those


#8

Alright if you are missing Socket and SecureSocket it is already implemented inside of MonaServer2.



And if you need to also deal with HTTP the work is already done. I think you have a lot of elements to help your way out and save a lot of time.

Everything concerning the flash part is here:

I hope it helps you.


#9

it is not as simple as that

the MonaServer Socket.cpp first is C++, and is made specific to MonaServer

it does not save time, it duplicates stuff

when I say I need to still implement a Socket class
it is because the goal of Redtamarin is to provide API and functionalities for other dev to program in the large whatever they want, I can not just include some random Socket.cpp and call it the day, jsut to “go faster”

The Socket.cpp above make a lot of assumptions, I can not connect events to it, “as is” it will not work on the AS3 side of things, some options are there, other options are missing, etc.


#10

Well then do it they way you want and we will see with what you will come up with. From my perspective if your code is modular this will not be difficult. But if you chose a design which is not based on any design patterns then yes your code is not easily adaptable with other projects.


#11

Well …
most of the Socket.cpp can be written in AS3

bool Socket::setNonBlockingMode(Exception& ex, bool value) {
#if defined(_WIN32)
	if (!ioctlsocket(_id, FIONBIO, (u_long*)&value)) {
		_nonBlockingMode = value;
		return true;
	}
#else
	int flags = fcntl(_id, F_GETFL, 0);
	if (flags != -1) {
		if (value)
			flags |= O_NONBLOCK;
		else
			flags &= ~O_NONBLOCK;
		if (fcntl(_id, F_SETFL, flags) != -1) {
			_nonBlockingMode = value;
			return true;
		}
	}
#endif
	SetException(ex, " (value=", value, ")");
	return false;
}
package
{
    import C.fcntl.*;
    import C.ioctlsocket.*;

    import shell.Runtime;

    public class Socket
    {
        private _id:int; // socket descriptor
        private _nonBlockingMode:Boolean;

        public function setNonBlockingMode( value:Boolean ):Boolean
        {
            if( Runtime.platform == "Windows" )
            {
                if( !ioctlsocket( _id, FIONBIO, value ) )
                {
                    _nonBlockingMode = value;
                    return true;
                }
            }
            else
            {
                var flags:int = fcntl( _id, F_GETFL, 0 );

                if( flags != -1 )
                {
                    if( value )
                    {
                        flags |= O_NONBLOCK;
                    }
                    else
                    {
                        flags &= ~O_NONBLOCK;
                    }

                    if( fcntl( _id, F_SETFL, flags ) != -1 )
                    {
                        _nonBlockingMode = value;
                        return true;
                    }
                }
            }

            return false;
        }

    }

}

That’s what people don’t understand with Redtamarin, you just need the C API syscalls,
you can perfectly replace the C++ part by the AS3 part.

If you just reuse C++, you duplicate stuff for nothing and with less utility in the general scheme of things.


#12

I see your perspective it become clear with your explanation. The way I was thinking this implementation is if we have a layer which is native code its execution will be faster if it is implemented with an existing solid code which made its proof.

Like an interface which handles the native instanciation when we declare from the AS3 side an object like NetConnection as an example. Something like Adapter design pattern. Similar to to how Flash Player handles the object instanciation when the VM is recognizing that AS3 requires a native code to be executed or native class which has a bridge AS3 class that needs to be created.

Because I don’t know the internals of redtamarin function this is my understanding how a VM works.

IMHO I think that where a code could be just used for speed purpose natively I don’t see the need to recode the whole thing in AS3 even if the there is the possibility to do so. I believe the part where redtamarin would shine is to be able to hook up native code and be usable without too much recoding in AS3 like a modular hooking of native code with automatic bridging. That automatic bridging could be having dlls or so libraries that redtamarin would parse to check which functions are available and when it founds something exported than redtamarin would create a Proxy class that would wrap the calls to methods in C++ class seamless in AS3. But for that you would need to to use something like OSGi or native extensions. Since RedTamarin is a mariage between native C++ and the VM that should not be complicated to implement. I see something like an almost automatic c++ to AVM glueing. To always recode everything in AS3 is too much waste of time when things can get automated. But sure it depends also how creative you are and how much technical competencies you have to be able to implement such mechanisms.

If the C++ part has its own handling of events then the only thing remaining to do is to notify the AS3 part like in Native Extension FREDispatchStatusEventAsync. There is really no need of handling the internal event system in AS3 just notify the AVM with an normal EventDispatcher. This is how my RTMFP server works withing my ANE that I created. When someone connects in the server the ANE notify my AS3 code that something happened in the C++ code I can intercept the message and decode either JSON object as one big string or even better encode the whole thing from C++ side via ByteArray and juste do what ever I want with the payload I receive.I can modularly in real time load and unload dynamic libraries which are implemented in C++ inside of an C++ OSGi runtime framework and I can call the function within AS3 in that C++ bundle that comes and go with live code reloading. That’s maybe too far advanced for how RedTamarin works but it work pretty well in Adobe AIR and Native Extensions I don’t see the impossibility why it should not work within redtamarin.

I don’t know if you get what I mean.


#13

I get what you mean but among the thousands different way to develop something it is just not the way we decided to go for.

When you just reuse an existing library in C++, it become blackbox,
it forces you to do things in specific ways, and block you to do things in other ways.

The whole design of the Redtamarin API is to be able to access low level C system call,
it is an integral part, not optional.

There are some C++ libraries that can be integrated, like zlib or opensll, but not all of them.

The design choice to use AS3 and to rewrite many things in AS3 is conscious;
because we know for a good decade if we tell people “sure recompile the C++ to do what you want”
this not gonna happen, but if we say instead “hey if you’re not happy with this API, you can write yours in AS3”, this works.

We got the same arguments with many people for years

  • you should do like Node.js
  • you should use libev or libevent
  • you should reuse cURL

and our answer is always the same thing

  • we want dev to be able to write their own Node.js
  • we want dev to be able to use sync or async, or modify their own event loop
  • we want dev to able to implement what cURL is doing but in AS3