ISBX / apprtc-ios

A native iOS video chat app based on WebRTC
BSD 3-Clause "New" or "Revised" License
1.34k stars 411 forks source link

any way to incorporate RTCDataChannel? #28

Open galileomd opened 8 years ago

galileomd commented 8 years ago

hi, learning webRTC on the fly.. any ideas on how to incorporate the RTCDataChannel?

looks like it needs an RTCPeerConnection but you're using ARDAppClient?

GaelHLago commented 8 years ago

I'm not really good with iOS, objective C and stuff, but i guess this lib is like the Android one from Google. You can find "- (void)peerConnection:(RTCPeerConnection)peerConnection didOpenDataChannel:(RTCDataChannel)dataChannel { }" at ARDAppClient.m, i guess it's an event wich is triggered once you receive a non-audio/video message from Data Channel (Android lib has an event "onDataChannel" in RTCPeerConnection class). Try something from here. I didn't find how to send a message, but Android lib got peerconnection.datachannel.send(ByteBuffer), should be the same.

GaelHLago commented 8 years ago

Ok so i did more research, and i also have problems with RTCDataChannel integration. I try to create one, but it doesn't seem to work, i've heard about protocol problems (but there is no doc or so telling how to solve it), anyone managed to use DataChannels on iOS ?

galileomd commented 8 years ago

i managed to get a swift version working but had to use the cocoapod precompiled libjingle_peerconnection in order to get things to work..

GaelHLago commented 8 years ago

Could you explain me ? Do you know what was blocking ? I'm pretty new to iOS so it's hard for me to burn everything and start from scratch ahah

galileomd commented 8 years ago

yea i’m also learning swift, obj c, and webRTC as i go so you’ll have to pardon my ignorance. let me see if i can translate the swift -> obj C to insert in your code, otherwise i can spin up a repo with my current code

On Monday, April 25, 2016 at 9:35 AM, Halftasoeur wrote:

Could you explain me ? Do you know what was blocking ? I'm pretty new to iOS so it's hard for me to burn everything and start from scratch ahah

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub (https://github.com/ISBX/apprtc-ios/issues/28#issuecomment-214330384)

GaelHLago commented 8 years ago

I think i can translate, it would be already helpful to have a working code. The problem was from DataChannel or PeerConnection ?

galileomd commented 8 years ago

sure, i will upload the repo sometime today

On Monday, April 25, 2016 at 9:41 AM, Halftasoeur wrote:

I think i can translate, it would be already helpful to have a working code. The problem was from DataChannel or PeerConnection ?

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub (https://github.com/ISBX/apprtc-ios/issues/28#issuecomment-214332633)

GaelHLago commented 8 years ago

Thanks

galileomd commented 8 years ago

sorry, still on my todo list.. i will extract and post the project eventually!

adarshvcdev commented 8 years ago

Hi galileomd,

Any update on RTCDataChannel integration?

GaelHLago commented 8 years ago

In order to integrate DataChannels, you have to :

set RTCDataChannelDelegate

@interface YourInterface () RTCDataChannelDelegate, ...

store your datachannel @property(nonatomic) RTCDataChannel *dataChannel;

set a new dataChannel


    RTCDataChannelInit *DataChannelInit = [[RTCDataChannelInit alloc] init];
    DataChannelInit.maxRetransmits = 0;
    DataChannelInit.isOrdered=false;
    DataChannelInit.maxRetransmitTimeMs = -1;
    DataChannelInit.isNegotiated = false;
    DataChannelInit.streamId = 25;
    RTCDataChannel *dataChannel =[_peerConnection createDataChannelWithLabel:@"commands" config:DataChannelInit];
    dataChannel.delegate=self;
    self.datachannel = dataChannel;

implement those methods in order to receive messages


- (void)peerConnection:(RTCPeerConnection*)peerConnection
    didOpenDataChannel:(RTCDataChannel*)dataChannel {
}
-(void) channel:(RTCDataChannel *)channel didReceiveMessageWithBuffer:(RTCDataBuffer *)buffer{
}
- (void)channelDidChangeState:(RTCDataChannel*)channel{
}

you can send data with :


- (void) sendDataToRemote:(NSString*)message{
    NSData *newData = [message dataUsingEncoding:NSUTF8StringEncoding];
    RTCDataBuffer *dataBuff = [[RTCDataBuffer alloc] initWithData:newData isBinary:true];
    BOOL *bDataSent = [self.datachannel sendData:dataBuff];
}

If you want to receive messages from remote DataChannel :

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    didOpenDataChannel:(RTCDataChannel*)dataChannel {
    NSLog(@"Datachannel is open name %@", dataChannel.label);
    dataChannel.delegate=self;
    self.dataChannelRemote = dataChannel;
}

Don't forget to import Datachannel.h and it should be ok. I believe you can't receive and send messages from the same datachannel, you have to open one from both sides. Tell me if it worked for you

adarshvcdev commented 8 years ago

Thanks for the support.

I am using the apprtc-ios code base to try the feature. I tried the code snippet but it is not connecting. State of RTCDataChannel is always kRTCDataChannelStateConnecting it is not getting connected.

Any help?

adarshvcdev commented 8 years ago

@Halftasoeur In which method I should initialize RTCDataChannelInit *DataChannelInit = [[RTCDataChannelInit alloc] init];

Means, after which event it should be initialized?

Thanks

GaelHLago commented 8 years ago

You need an object RTCPeerConnection to create your RTCDataChannel, but not the RTCDataChannelInit. You can create it whenever you want, but you can set it when your establish your connection when the state comes to kARDAppClientStateConnected. (didChangeState) I know there is something with the streamID, people say it is useless and some say it is mandatory, so i don't really know, i set it at the moment, but I will take a look at it later try to set it if you didn't.

hengtelin commented 8 years ago

BenjaminFaal's new pull request is containing a messaging functionality. So I assume that his commits would include a RTCDataChannel implementation. Maybe you can have a look.

ajaysinghthakur commented 7 years ago

@Halftasoeur would like if there is any full working example. i made server in nodejs using tutorials point webrtc tutorial and try to implement it client in ios and able to do that only data channel is not sending data whereas i am receiving data properly

GaelHLago commented 7 years ago

I don't know exactly what you need.

http://simpl.info/rtcdatachannel/ might be what you are looking for ?

What you mean is : You have a datachannel myDataChannel

you open it, and in the method didReceiveMessageWithBuffer you receive the messages.

But when you try to send something with

MyDataChannel.sendData:(dataBuffer) nothing happens ?

sendData returns a bool, check if it's true. Are your opening the DataChannel in your iOS app or in your server ? (maybe you missed something when opening the datachannel ?)

ajaysinghthakur commented 7 years ago

i had gone through the above example my code is working fine on web side the problem is on the implementation on ios side would you able to suggest any ios sample on rtcdatachannel

GaelHLago commented 7 years ago

I don't have sample, but https://stackoverflow.com/questions/37850376/impelementation-of-rtcdatachannel-of-webrtc-in-ios is correct.

Don't forget the delegate in your view controller

AMKaffiOS commented 7 years ago

@Halftasoeur If i want to send and receive messages, how should i initialize the datachannel? thanks

GaelHLago commented 7 years ago

@AMKaffiOS Datachannels are made to send and receive messages. See one of my previous posts 14 Jun 2016, I explain all the implementation (and i made a mistake saying you can't send and receive informations).

Maybe you are opening the DataChannel from an other client, so :

There is a callback named onDataChannelOpen (i guess, i don't have the code right now, but just check the doc). From there, you can get the datachannel you opened from the other client, name it, attach a delegate, and so you will be able receive and send messages

Check previous messages, everything is explained, there are some snippets of code :)

AMKaffiOS commented 7 years ago

@Halftasoeur Thank you very much, under your guidance, as I created an object of RTCPeerConnection in the time to create a datachannel(localDataChannel) object, use this object to send a message,

Then I retain a datachannel(remoteDatachannel) object in the callback method named didOpenDataChannel , use this object to send a message, Then I can send and receive messages.

RTCDataChannelConfiguration dcConfig = [[RTCDataChannelConfiguration alloc] init]; dcConfig.maxRetransmits = 1; dcConfig.isOrdered = NO; dcConfig.maxPacketLifeTime = -1; dcConfig.isNegotiated = NO; dcConfig.channelId = -1; dcConfig.protocol = @""; RTCDataChannel localDataChannel = [_peerConnection dataChannelForLabel:@"commands" dcConfig]; localDataChannel.delegate=self; self.localDataChannel = localDataChannel;

GaelHLago commented 7 years ago

You can use the same datachannel for sending and receiving.

Let's say you have 2 clients (or 1 server and 1 client) :

Client 1 :

Open a DataChannel :

  RTCDataChannelInit *DataChannelInit = [[RTCDataChannelInit alloc] init];
    DataChannelInit.maxRetransmits = 0;
    DataChannelInit.isOrdered=false;
    DataChannelInit.maxRetransmitTimeMs = -1;
    DataChannelInit.isNegotiated = false;
    DataChannelInit.streamId = 25;
    RTCDataChannel *dataChannel =[_peerConnection createDataChannelWithLabel:@"commands" config:DataChannelInit];
    dataChannel.delegate=self;
    self.datachannel = dataChannel;

Your datachannel is open, you can now send or receive messages on Client 1.

Client 2 : You need to watch for a new DataChannel, so implement it :

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    didOpenDataChannel:(RTCDataChannel*)dataChannel {
    NSLog(@"Datachannel is open name %@", dataChannel.label);
    dataChannel.delegate=self;
    self.dataChannelRemote = dataChannel;
}

Ok, now you can use the sames methods as the Client 1, send and receive messages.

//message received
-(void) channel:(RTCDataChannel *)channel didReceiveMessageWithBuffer:(RTCDataBuffer *)buffer{
}

//State changed
- (void)channelDidChangeState:(RTCDataChannel*)channel{
}

//a sample to send datas over the DataChannel
- (void) sendDataToRemote:(NSString*)message{
    NSData *newData = [message dataUsingEncoding:NSUTF8StringEncoding];
    RTCDataBuffer *dataBuff = [[RTCDataBuffer alloc] initWithData:newData isBinary:true];
    BOOL *bDataSent = [self.datachannel sendData:dataBuff];
}

I hope it helps

AMKaffiOS commented 7 years ago

Thank you very much, according to your method, and now client can already use a same datachannel object communicate with the server.

Rahulgupta-cdnsol commented 6 years ago

I am newer to webRTC so please let me know How to create peer connection object?

vincenzourbisaglia commented 6 years ago

See my sample https://github.com/vincenzourbisaglia/apprtc-ios/commit/1173b58ae8a28fe6a1b6aa17b4b72dcaf23dfdc5