I am new to socket programming and don't have much idea on how it works, Here is the use case, Im developing an iPhone app, where users stream real time audio originated from another iPhone device (in short Multi casting)
What I have done so far:
I opened a port on server which keep listening to incoming data from clients. On the iOS side, i implemented methods thats read the packets received on the server and process it accordingly (i have used GCDAsyncSocket)
Problem where I need help:
The above use case works perfect for 2 users, one that sends the audio data to the server and the other one reads that data to play audio. But actually there would not always be a single user originating audio data, they could be more than 100+, Now when all of them are sending different audio data to server how could i filter data for the listeners that everyone receive only there data, I overcome this problem adding a token on every packet like
unique_token:<ffdefa09 fedead3...... //Audio Data
But this process is way too slow as every client is listening all the packets and only process the ones with the token they are assigned.
Is there anyway, we can make a peer to peer connection by which the originating device become server and only sends data to its listeners and don't bother anyone else?
Can't you add something like a light protocol before you start steaming audio data to server ?
iPhone -> server [Request: Start Stream Audio]
server -> iPhone [OK: TCP Port:4444]
// iphone sending audio packets to port 4444
iPhone2 -> server [Request: Start Stream Audio]
server -> iPhone2 [OK: TCP Port:4445]
then the server can filter all audio channels with TCP port ID instead of packet ID (or maybe I misunderstood your issue)
Btw I don't think you can do any "real" P2P with iPhone on cellular networks because of providers firewalls
for every end who send the audio data, you create a socket and recv audio data, and for every end who receive the audio data, you create a socket and send audio data.
P2P is lots of work , because many device are behind the public address.
You need to separate your command data from your streaming/audio data.
First you need the iphones to tell the server what they want,
iphone 1: "i want to stream this data with id 1"
iphone 2: "i want to listen to stream with id 1"
that way the server can tell the iphone where to connect for getting the data it needs, as HaneTV suggested with port numbers
Related
There are some ios sip applications who are able to communicate with a UDP only SIP Server.
As I know iOS allows only TCP connection to remain open in the background but most of the SIP providers are supporting only UDP.
I have noticed that iOS application 3CXPhone has a "NAT helper mode" and it is able to keep the communication in background with a 3CX Phone system who is UDP only. Dose anyone know what trick do they use? I am developing an SIP app and I have to make it work for the UDP only SIP providers.
I know there are multiple questions regarding UDP socket in background on SO but none of them has a useful answer or the solution proposed there dose not work anymore (starting from iOS 6).
Until now I am aware of 2 possible solutions:
1. Use some GPS events and during that events maintain the socket communication too. After that try to trick apple and get your app in the store.
2. Use a SIP proxy in the middle (B2BUA). But in the 3CXPhone "NAT helper mode" I am not seeing any sip proxy configuration.
If you really need a UDP socket you will need a few things:
UIRequiresPersistentWiFi: to ensure that iOS connects to Wi-Fi and doesn't turn it off after some time (I'm assuming you want Wi-Fi as well, if not just ignore this one)
Play an empty audio in the background in a loop to keep your application active.
Have a timer that pops every ten seconds or so and sends a small (e.g. crlf) message to the server.
The last step is needed to keep the UDP connection open in the network. If you don't send anything often, someone in the network (e.g. a router) will close it.
The empty audio file is the only way to ensure you can do something in the background in short intervals (the ten second timer).
After writing all that: this will consume a lot of battery. Users will not leave your app running for long.
Most modern SIP servers support TCP. You should really spend your time on a TCP solution. The UDP one won't be accepted by your users.
I want to make a utility app which communicates with other clients running on other devices.
One app becomes the master and waits for slaves. It connects with the slaves and sends them lightweight data in real time. The devices are within 10 meters range of eachother and it is not intended for long distance communication so bluetooth would be ok. Low latency and time synchronisation is very important.
I think GameKit peer to peer would be an option for this? What other options are there? Is there a open source framework that makes this very easy to set up?
I am not an expert but Bluetooth- Wi-fi - Bonjour would be your options I guess. GameKit would be the best option to use.
From Matthijs Hollemans:
GKSession has a method called sendDataToAllPeers:withDataMode:error: that will send the contents of an NSData object to all connected peers. You can use this method to send a single message from the server to all the clients. The message in this case is an NSData object, and what is inside this NSData object is completely up to you.
For peer to peer connection;
A packet is at least 10 bytes. These 10 bytes are called the “header,” and any (optional) bytes that may follow are the “payload.” Different types of packets have different payloads, but they all have the same header structure
You can check this blueetooth game tutorial
Matthijs Hollemans: Snap
Can anyone tell me, is it possible to create an iPhone chat app without using a server. I just need only two connections.
I guess it would be possible by the two devices have to be directly connected (i.e. bluetooth, wifi, etc.). They may therefore discover each other (at an application layers i.e periodically broadcasted UDP packets on a give port?), create a tcp connection (or UDP but in this case you should ensure at application level all the sent messages are actually received..) on the top of which the actual chat protocol can be realized
From my understanding you cannot socket a connection between two iPhones (correct me if I'm wrong). So what I would like to do is have one server sitting between the client application that accepts messages and redistributes them to the appropriate person(s). Essentially the application is going to allow people to have a shared map that has their locations and everyone can annotate it.
1) I have been reading and researching into the CFStream class, but I'm curious to know if it might be better to just use the C send() and recv() functions. They almost seem much easier to use. What does CFStream offer over the native C socket functions that make it a better option?
2) Since I need the phone to actively listen for updated shared user locations/new annotations from other users, my plan was to periodically have the phone poll the server for any "news" from other users (say every minute or two). Is there anyway the phone could spin off a new thread in the application that is constantly waiting for incoming traffic? It would make life easier to be able to have a user annotate the map, push that to the server which then immediately updates the appropriate users maps.
I have been using example socket code from Jonathan Zdziarski's iPhone SDK book from O'Rielly Media to just try sending messages between a server and iPhone emulator (the classic knock knock joke server/client). However, after sending 1 or 2 messages the server gets stuck "receiving." The code runs perfectly when not sent from an emulator, as I can seemly spam the client send function and get a response from the server each time. Could the server be hanging because I use send() and recv() instead of the CFRead and Write stream?
You can socket iPhone applications using bonjour, or even GameKit (which is what I use because it manages all data for you).
Im currently developing a chat client for the iphone.
Server-side there is a node.js with Socket.IO and on the iPhone an Socket.IO client
( https://github.com/DanLite/socket.IO-objc )
My Question is:
Will the iPhone battery affected with an open TCP connection and not sending or receiving data for like 3-4 Minutes?
What is better for battery life? A constant tcp connection or multiply HTTP requests.
Thanks
Edit:
I have a chat + other functions like (changing name, checking friends status, edit settings)
Edit 2:
Looks like WhatsApp doing it with a tcp connection
When TCP connection is opened both parties posses information about it (remote ip:port, local ip:port). That information is a mere data structure in the memory.
As long as there is no RST packet received or timeout occurred connection is considered to be opened.
When you send data over connection you start consuming CPU and force underlying wireless mobile network module to send signal hence consume battery.
That is why it is better to keep TCP connection for as long time as possible and prefer batching over chatty communication (combine several application messages).
On the other hand you should be prepared to the situation when network coverage is poor and you will have to constantly reopen TCP connection thus consume battery.