Scriptico

iPhone chat. Native RTMP Library for iOS in Action

iOS chatIn this article I would like to show how to use RTMP on iPhone, or on iOS in general. Although the RTMP protocol known as a part of Flash Applications, in this article you will not find the ActionScript code because the client library is completely native. At the end of this article you will find all important links and the source code.

I created a simple chat application for iOS in order to demonstrate how it works. The application’s use-case is pretty simple: iOS client connects to the server, and the server send back to the client a greeting message. As soon as the client connected to the client he can send messages to all connected clients and receive their messages as well. Also, for everybody who are not familiar with the RTMP protocol I would like emphasize that the connection between the client and server is permanent.

Server side

The server-side is powered by WebORB for .NET, and in general the code is pretty simple; moreover, the server-side code absolutely do not care about the client type, and from this prospective it is absolutely multi-platform. Fortunately (or unfortunately?), I missed below a short story how to install WebORB, configure messaging applications, and how a messaging application works in general; however, you will easily can find this information in the WebORB documentation. So, lets consider the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Weborb.Messaging.Server.Adapter;
using Weborb.Messaging.Api;
using Weborb.Messaging.Api.Service;

namespace HabraSample
{
    public class AppHandler : ApplicationAdapter
    {

        public override bool appConnect(Weborb.Messaging.Api.IConnection conn, object[] parms)
        {
            bool connected = base.appConnect(conn, parms);

            String clientName = (String)parms[0];

            conn.setAttribute("ClientName", clientName);

            if (connected && conn is IServiceCapableConnection)
                ((IServiceCapableConnection)conn).invoke("messageToClient", new object[] { "Hello, " + clientName });

            return connected;
        }

        public override void appDisconnect(Weborb.Messaging.Api.IConnection conn)
        {
            String message = conn.getAttribute("ClientName") + " left the application";

            this.pushData("messageToClient", new object[] { message });

            base.appDisconnect(conn);
        }

        public void messageToAll(String message)
        {
            this.pushData("messageToClient", new object[] { message });
        }

        private void pushData(String methodName, object[] args)
        {
            if (scope.getClients().Count == 0)
                return;

            IEnumerator connections = scope.getConnections();
            while (connections.MoveNext())
            {
                IConnection connection = connections.Current;
                if (connection is IServiceCapableConnection)
                {
                    ((IServiceCapableConnection)connection).invoke(methodName, args);
                }
            }
        }
    }
}

What do we have here? The appConnect method will be fired as soon as a new client tries to connect to the server. Also, with a new connection the server application receives a client name through the parameters passed by clients, stores the client name in to the connection attributes, and invokes the messageToClient method with a greeting string as a parameter. Now, the connected user is able to send messages to the all connected clients. The client code just invokes the messageToAll method on the server side, and the server start broadcasting this message to all connected clients. As I emphasized above, the RTMP connection between the iOS client and the RTMP server is permanent, and the data broadcast in the real-time mode!

Client code

On the client side we must add a client RTMP library developed by Midnight Coders, and make all required steps by follow the documentation. Sorry, but I didn’t include this borring stuff, so please go to the Midnight Coders site, read carefully and have a fun :). But before you will go lets look on some important details in the client code.

1. Connect / Disconnect

#import "SettingsController.h"

@interface SampleViewController : UIViewController {
   ....
   RTMPClient	   *socket;
   ...
}
...

- (void) doConnect:(id)sender;
- (void) doDisconnect:(id)sender;
....

@implementation SampleViewController

@synthesize socket;

-(void)doConnect:(id)sender {
    socket = [[RTMPClient alloc] init];
    socket.delegate = self;
    ...
    [socket connect:[settings stringForKey:@"host"] port:[[settings stringForKey:@"port"] intValue]  app:[settings stringForKey:@"appName"] params:parameters];
    ...
}

-(void)doDisconnect:(id)sender {
   ...
    [socket release];
    socket = nil;
}
...
#pragma mark -
#pragma mark IRTMPClientDelegate Methods 

-(void)connectedEvent {
    state = 0x01;
    connectBtn.title = @"disconnect";
}

-(void)disconnectedEvent {
    ....
    [self performSelector:@selector(doDisconnect:) withObject:nil afterDelay:0.1f];
}

-(void)connectFailedEvent:(int)code description:(NSString *)description {
    [self performSelector:@selector(doDisconnect:) withObject:nil afterDelay:0.1f];
}

2. Processing Data

-(void)resultReceived:(id )call {
    int status = [call getStatus];
    // NSString *method = [call getServiceMethodName];
    NSArray *args = [call getArguments];

    if (status == 0x02) // client's method invocation
    {
        [messages addObject:args];
        [table reloadData];
    }
}

The code is simply, so let’s look on it briefly. We must create an instance of the RTMPClient class, we can connect disconnect to the server, and we do have three type of events: connected, disconnected, and connection failed. You will find absolutely amazing description in details about it in the official documentation.

How it looks

iOS chat

Conclusion

RTMP is not only a part of Adobe stuff, and there is no any limitation since Adobe opened the protocol. The library was written on “pure” objective-c, it is light-weight, and do not required any third-part frameworks. Moreover, the WebOBR mobile team are hardly working on the implementation many features such as video and audio broadcasting, and in the closer future it will be available for the public download. Also, there is no difference from the server-side prospective as well as from client side; you can use the library in your iOS application and Wowza server, FMS server etc.

Resources

Category: Examples, Examples (RTMP), iOS, WebORB (.NET)

Tagged:

Leave a Reply

ERROR: si-captcha.php plugin: GD image support not detected in PHP!

Contact your web host and ask them to enable GD image support for PHP.

ERROR: si-captcha.php plugin: imagepng function not detected in PHP!

Contact your web host and ask them to enable imagepng for PHP.