-1

I want to develop an iOS app which should be able to send messages to other WiFi direct enabled devices (no matter if it is an iOS device or Android device) and receive messages from them.

I found a suitable library ZeroMQ which can be used to accomplish the task. I have compiled the library for iOS successfully.

I reffered szehnder's sample code but the app doesn't do anything. It shows a blank table view only. I checked in the code and found that the code to receive a message is present there but the method to send the message is empty.

How can we detect other WiFi direct devices? Send and receive messages to them? Any pointers are highly appreciated.

As suggested by Jason, I am adding whatever I have achieved till now: I have an android app which connects to other android devices using WiFi direct and sends and receive messages from them, and uses ZeroMQ. I need to communicate with that app with my iOS app.

Below is my code to receive the messages:

-(void) setupSockets:(ZMQContext*)myContext {

 ZMQSocket *subscriber = [myContext socketWithType:ZMQ_SUB];
[subscriber setData:nil forOption:ZMQ_SUBSCRIBE];
[subscriber connectToEndpoint: [NSString stringWithFormat:@"tcp://%@:%@", @"192.168.49.1", @"26665"]];

while (1) {

    NSData *m = [subscriber receiveDataWithFlags:0];
    if (m!=NULL) {
         NSString *s = [NSString stringWithUTF8String:[m bytes]];
        NSLog(@"Message: %@", s);

        [self performSelectorOnMainThread:@selector(postMessageNotification:) withObject:s waitUntilDone:NO];

    }
    sleep(3);

}

}

Here 192.168.49.1 is the ip address of the host android device and 26665 is the port number used to receive messages. The control reaches up to call of receiveDataWithFlags: successfully but does nothing after that.

Now to send the data:

-(IBAction) sendMessageClicked:(id)sender {
NSString *pubEndPoint = [NSString stringWithFormat:@"tcp://%@:%@", @"192.168.49.1", @"26666"];
ZMQSocket *pubSocket = [objMeeps.context socketWithType:ZMQ_PUB];
[pubSocket connectToEndpoint:pubEndPoint];

NSData *msg = [@"hi" dataUsingEncoding:NSUTF8StringEncoding];
   [pubSocket sendData:msg withFlags:ZMQ_NOBLOCK];
}

The method gives an error message ZMQLogError: *** <ZMQSocket: 0x17405fdd0 (ctx=0x174029480, type=ZMQ_PUB, endpoint=tcp://192.168.49.1:26666, closed=0)>: zmq_send: Resource temporarily unavailable. When I searched regarding this error I got that the error is occurring due to absence of any receiver but my iPhone is connected to the WiFi network created by the android host using WiFi Direct.

I am new to ZeroMQ so might be missing something very small. Hope this clarifies the issue enough.Please guide me regarding this.

Yogi
  • 3,578
  • 3
  • 35
  • 56
  • http://stackoverflow.com/questions/28906948/peer-to-peer-android-and-ios-with-wifi-direct-multipeer-connectivity – Rilwan Mar 08 '16 at 06:03
  • @Rilwan: Thanks for the response. But the quoted question doesn't tell anything about ZeroMQ. I have an android app which uses ZeroMQ to pass the message and I want to communicate with it using an iOS app so I think I will need to implement ZeroMQ only. Do you have anything regarding that? – Yogi Mar 08 '16 at 06:07
  • Ok.Sorry, I dont know about ZeroMQ. I thought you are trying to implement a peer-peer connection between ios and android as mentioned in you first paragraph. – Rilwan Mar 08 '16 at 06:18
  • Try to be a little more explicit in your question, maybe add some code that you expect to be running that isn't producing the output you expect - I know ZMQ but little of iOS so rather than learn how to navigate the sample code you linked to it would be helpful if you added the code directly to the question and explained your understanding of how it works. – Jason Mar 08 '16 at 21:14
  • @Jason: Thanks for your response. I have added the code I have done so far in my app. Please have a look now. – Yogi Mar 09 '16 at 06:32

1 Answers1

1

So you say tcp://192.168.49.1:26666 is the address of your Android host, but so far as I can tell you're trying to publish and subscribe from your ios device, at least for this example. So, let's be explicit: for this example, ignore your Android device and just try to get your ios application talking to itself.

Step 1: use the ip:port for your ios device

ZMQ has two sides to every connection, one side that "binds" (and could be considered the server) and one side that "connects" (and could be considered the client). Your choices are flexible, but for the sake of example it's probably best for your publisher to bind and your subscriber to connect. Right now, you have both sides connecting. This is likely the cause of the error you're seeing.

Step 2: change your pub socket to bind on its address rather than connect

When using PUB/SUB, you must subscribe to the "topics" you want. In your example code you're subscribing to "NASDAQ". For you to receive messages, the text of the message must begin with your subscriber topic, for instance "NASDAQ:hi" would get through your subscription filter.

Step 3: change your zmq_subscribe option to subscribe to an empty string "" to get every message that comes through

Making those three changes should put you on the right track. I highly suggest you read the guide, it covers these sorts of basic usage guidelines and has a fair body of ios example code to boot.

Jason
  • 13,606
  • 2
  • 29
  • 40
  • Hi Jason, I tried the steps you mentioned above. I am also going through the guide and iOS examples in it. Now I am able to connect to my android host. Whenever I send some data from the host, initially I get `: zmq_recv: Resource temporarily unavailable`. As per my readings initially the socket isn't ready so may be giving this error but after that it gives error `zmq_recv: Operation timed out` again and again. I have edited my answer with my updated code to receive the data. Plz have a look – Yogi Mar 09 '16 at 12:54
  • Why are you connecting to your android host at all? Both your publisher and subscriber are on your ios device, correct? Or am I missing something? Make sure both your up-to-date PUB code *and* up-to-date SUB code are in your question, even if one is on android and the other on ios, because in your question it still doesn't show either side as binding. Also, I doubt that subscribing to `nil` is identical to subscribing to the empty string `""`, but here again I'm not as familiar with objective C – Jason Mar 09 '16 at 14:49
  • Hi Jason, my publisher is on android device. I have removed the code of PUB socket from my `-(void) setupSockets:(ZMQContext*)myContext` method. I need to connect to android host so I have included ip address of that device. The problem is I am getting error in zmq_recv as 'Operation timed out'. Please correct me if I am missing something, I am connecting successfully to the host as on android side connection logs are properly generated.`-(IBAction) sendMessageClicked:(id)sender` is not used while I am receiving the data – Yogi Mar 09 '16 at 15:01
  • Assuming that your publisher code on your android device is set up appropriately, I would suggest you change your subscription from `nil` to `[subscriber setData:[NSData dataWithBytes:"" length:strlen("")] forOption:ZMQ_SUBSCRIBE];` (I based that line on the example [here](http://zguide.zeromq.org/m:wuclient)). I never see a `null` or `nil` subscription in the code examples *anywhere*, I suggest you use an empty string. The correct subscription is a very important piece of the `PUB/SUB` model. – Jason Mar 09 '16 at 15:16
  • Hi Jason, I tried your suggestion. It still gives timeout error. As other android devices are able to connect and send messages to android host, I can say that the code for publisher is appropriate – Yogi Mar 09 '16 at 15:24
  • I just looked back at your receiving code - in your original example, you were using `NSData *m = [subscriber receiveDataWithFlags:ZMQ_NOBLOCK];`, and you changed that to `NSData *m = [subscriber receiveDataWithFlags:0];` - if you're making a blocking call to `receive` and no messages are received within the timeout window, then it'll fail with that message. Based on the remainder of your code, it looks like you intend to be making a non-blocking call, so I suggest you change it back to what you had originally. – Jason Mar 09 '16 at 16:30
  • Hi Jason, Thanks for taking time to answer my query. I restored the change you mentioned in your comment but it doesn't have any effect. Still getting `mq_recv: Operation timed out` errors many times. – Yogi Mar 10 '16 at 06:07
  • Time to go back to basics - take one of the pub/sub examples from the guide, written in objective-c (such as this [example with objective-c code](http://zguide.zeromq.org/page:all#Getting-the-Message-Out)) and try to run it directly, without modification. If that works, move the [server to java on your android device](http://zguide.zeromq.org/java:wuserver), only change the address endpoint and see if that works. If *that* works, then attempt to modify your working client code to point to your application: change the endpoint, subscription, etc. – Jason Mar 10 '16 at 15:11
  • Hi Jason, the error was regarding how zmq_send and zmq_receive were working in older version and how they work in newer one. Previously the methods were returning error code which now returns number of bytes processed and my implementation (or the snippet I was using) considered it as error code. – Yogi Mar 11 '16 at 09:57
  • Ah, yep, that makes sense. Glad you got it figured out! – Jason Mar 11 '16 at 11:48
  • Thanks for your valuable help Jason – Yogi Mar 11 '16 at 11:57