Cfmessageport of iOS interprocess communication

Source: Internet
Author: User

Cfmessageport of iOS interprocess communication 

iOS systems are name-gated and each app's range of activities is strictly limited to its own sandbox. However, iOS provides a number of interprocess communication mechanisms, and cfmessageport is one of them.

As can be seen from the class name, Cfmessageport belongs to the Core Foundation layer, its implementation is open source, the code can be found in Apple's open source code base.

How to use

1. Message Recipients

The recipient of the Cfmessageport port message needs to implement the following features:

1.1 Register for monitoring

Message receivers need to register for message snooping in the following ways:

-(void) startlistenning{if (0! = Mmsgportlistenner && cfmessageportisvalid (Mmsgportlistenner)) {Cfmes        Sageportinvalidate (Mmsgportlistenner); } Mmsgportlistenner = Cfmessageportcreatelocal (Kcfallocatordefault,cfstr (Local_mach_port_name),        Onrecvmessagecallback, NULL, NULL);        Cfrunloopsourceref Source = Cfmessageportcreaterunloopsource (Kcfallocatordefault, Mmsgportlistenner, 0);        Cfrunloopaddsource (Cfrunloopgetcurrent (), source, kcfrunloopcommonmodes); NSLog (@ "Start listenning");}

Where local_mach_port_name is defined as:

#define LOCAL_MACH_PORT_NAME "Com.wangzz.demo"

After viewing the source, Cfmessageport is actually implemented via Mach port. Mach Port is a port-based input source provided by the iOS system and can be used for thread or interprocess communication. The input source types supported by Runloop include port-based input sources, so you can use Runloop as the listener for Cfmessageport port source events.

The above code has several points to explain:

    • A local Cfmessageportref object can be created by cfmessageportcreatelocal

    • It is very important that the Cfmessageport object is uniquely identified by a string, where the string is defined by the macro local_mach_port_name;

    • The Cfmessageport object is created with the callback function Onrecvmessagecallback of the port source event, which is used to handle the port source event;

    • The created object is added to the runloop as an input source to listen for port source events, and when Runloop receives the corresponding port source event, it invokes the callback method specified in the previous step;

1.2 Implementing Callback Methods

The callback function is the Cfmessageportcallback type, which is defined in part:

typedef cfdataref (*cfmessageportcallback) (Cfmessageportref Local, SInt32 msgid, cfdataref data, void * info);

The meanings of each parameter are:

    • Cfmessageportref Local

The Cfmessageportref object that currently receives the message.

    • SInt32 MsgId

This field is useful for identifying messages. If the communication process contract number each msgid corresponding data structure, you can achieve more complex communication.

    • Cfdataref data

The real data part of the communication.

    • void *info

The Info field for the Cfmessageportcontext object that is specified when you use the Cfmessageportcreatelocal method to create port ports is usually empty.

This callback method can return a cfdataref type of data to the sender of the port message, which is also important for efficient communication between the two parties.

The implementation of my callback function Onrecvmessagecallback:

Cfdataref onrecvmessagecallback (Cfmessageportref local,sint32 msgid,cfdataref cfdata,  void*info) {    nslog (@ "onrecvmessagecallback is called");         NSString *strData = nil;         if  (Cfdata)     {           const uint8  * recvedmsg = cfdatagetbyteptr (CfData);                 strdata = [ Nsstring stringwithcstring: (char *) recvedmsg encoding:nsutf8stringencoding];               /**                    implementing data parsing operations                    **/                  nslog (@ "receive message:%@", Strdata);    }     //to test, generate return Data     NSString *returnString = [NSString  stringwithformat:@ "i have receive:%@", Strdata];        const  char* cStr = [returnString UTF8String];         NSUInteger ulen = [returnString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];       cfdataref sgreturn = cfdatacreate (NULL,  (UInt8 *) Cstr, ulen);         return sgreturn;}

The method is simple to implement, parsing the agreed data (the contract in the test code is a string), in order to test, and generate a CFDATAREF data returned to the sender of the port message.

1.3 Canceling port snooping

You can unblock port ports in the following ways:

-(void) endlisenning{cfmessageportinvalidate (Mmsgportlistenner); Cfrelease (Mmsgportlistenner);}

Cfmessageportinvalidate stops the send and receive operations for the port message, and only the Cfrelease,cfmessageportref object is called to actually be released.

2. Message sender

Send some code as follows:

-(nsstring *) Sendmessagetodameonwith: (ID) Msginfo msgid: (Nsinteger) msgid{    //   Generate remote port    cfmessageportref bremote =  Cfmessageportcreateremote (Kcfallocatordefault, cfstr (mach_port_remote));         if  (nil == bremote)  {             nslog (@ "bremote create failed");                 return nil;    }         //  Build Send data (string)     NSString     *msg = [nsstring stringwithformat:@ "%@",msginfo];         nslog (@ "send msg is :%@", msg);         const  char *message = [msg utf8string];        cfdataref data,recvdata = nil;         data = cfdatacreate (null,  (UInt8 *) message,  strlen (message));        //  perform the send Operation      Cfmessageportsendrequest (Bremote, msgid, data, 0, 100 , kcfrunloopdefaultmode,  &recvdata);        if  (nil == recvData)   {            nslog (@ "RecvData date is  nil. ");                 cfrelease (data );                 Cfmessageportinvalidate (bremote);                 cfRelease (bremote);                 return nil;    }    //  Parse return Data      Const uint8  * recvedmsg = cfdatagetbyteptr (RecvData);         if  (nil == recvedmsg)  {             nslog (@ "Receive date err.");                 cfrelease (data );                 Cfmessageportinvalidate (bremote);                 cfrelease (bremote);                 return nil;    }    nsstring    *strmsg = [nsstring stringwithcstring: (Char  *) Recvedmsg encoding:nsutf8stringencoding];        nslog (@ " %@ ", STRMSG);         cfrelease (data);         cfmessageportinvalidate (bremote);         cfrelease ( bremote);         cfrelease (RecvData);         return strmsg;}

Where mach_port_remote is defined as:

#define MACH_PORT_REMOTE "Com.wangzz.demo"

It is relatively simple to send a message, first to generate a remote cfmessageportref through Cfmessageportcreateremote, It is important to note that when Cfmessageportcreateremote is passed, the string uniquely identifies the mach_port_remote must be the same as the string unique to the message recipient when creating the local cfmessageportref.

By looking at the source code discovery, Cfmessageportcreateremote will be based on Mach_port_ The remote defined string is a unique identifier for getting the message receiver to use the same string created by cfmessageportcreatelocal to create the underlying Mach port port, which enables sending information to the message receiver.

If the message receiver has not yet been created or failed to create a local port through cfmessageportcreatelocal, it is definitely a failure to attempt to create the remote port via Cfmessageportcreateremote.

Description

    • Unfortunately, in iOS7 and later systems, the Cfmessageport communication mechanism is no longer available.

When you create a Cfmessageportref object using Cfmessageportcreatelocal/cfmessageportcreateremote, it will fail, as stated in the official documentation:

This method isn't available on IOS 7 and Later-it would return NULL and log a sandbox violation in syslog. See Concurrency Programming Guide for possible replacement technologies.
    • Cfmessageport can only be used for local process communication.

    • Cfmessageport is based on the Mach port communication method, not only can be used for process communication, can also be used for inter-thread communication, but the inter-thread communication with GCD and cocoa provided by the native method, has been very convenient to implement, no need to use Cfmessageport.

    • Process Communication usage Scenarios

The multi-tasking mechanism of iOS system makes interprocess communication basically only for jailbreak development. The common scenario is that the front end has a UI program for the interface display, and the backend has a Daemo daemon for task processing.

Demo Project

Specifically done a demo project, in order to better demonstrate the use of Cfmessageport, can be downloaded to csdn.

To simulate the interprocess communication scenario, I cfmessageportreceive the message receiving process into a program that can play music in the background so that it can continue to survive after it is cut into the background.

Since Cfmessageport no longer supports iOS7 and later systems, this demo is tested on the IOS6 system.

How to use the demo:

    • Cfmessageportreceive Start, click Start listenning Create Cfmessageport interface and start listening port message, and then cut cfmessageportreceive to the background;

    • Start the Cfmessageportsend program, write the content in the input box, and click the Send button to communicate with Cfmessageportreceive.

    • Messageport There will be log output during the communication process, you can view the log using the following methods:

1. Real Machine

Select: Xcode->window->organizer->devices, and then check the console window of the current device on the left side of the window.

2. Simulator

Select: Open the System log with debug, simulator, or use the shortcut key directly./Open the system console to view the log directly.

Reference documents

    • CF-855.14

    • Threading Programming Guide

    • Cfmessageport Reference

Cfmessageport of iOS interprocess communication

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.