Comments (13)
Thanks, I think it would indeed be cool to have it as a complete usage example for the library! What protocol do you use for communication?
from libdatachannel.
Please where is the enhancement?
from libdatachannel.
Hi, sorry for the lack of communication, I made a little video of the demo we made. Maybe take a look and let me know if you're interested? https://www.dropbox.com/s/mgxr3xvgegklg3u/webbrowser-native-webrtc.mov?dl=0
from libdatachannel.
A bit more info. The demo has 3 parts.
- A native client (this is in fact your offerer example which has been modified to:
- create a data channel
- once the connection is set up, it base64 encodes it and passes it to the web client via the query string.
- It then polls the node js server every 2 seconds to try to obtain the details of the web client.
- once it gets the details of the connection, it finishes off the handshake.
- you can now send messages to the web client in the terminal
-
A very minimal node js server, this allows the web client to post its connection details for the native client to complete the handshake.
-
A web client written in pure javascript, this:
- looks for a connection info in the query string
- creates a connection
- posts the details of its connection to the node server
- allows users to send and receive messages
from libdatachannel.
As I explained, this is hack day code, but I made a PR for you to have a closer look. #62
from libdatachannel.
Thank you, I will look into the code
from libdatachannel.
I've noticed there's actually 2 implementations of the server, you can ignore the rust code
from libdatachannel.
Ok, Thank you for the clerance
from libdatachannel.
Can you help with a bug I am having with my code. If you can, sorry for the distrubance,I am writting the code in c but I keep getting the error. You dont have to look at the whole code.
i am having isse in the while statement where this two functions are
rtcSetRemoteDescription(peer->pc, sdp, "offer");
rtcAddRemoteCandidate(peer->pc, candidate, NULL);
` 0: Exit / 1: Enter remote description / 2: Enter remote candidate / 3: Send message / 4: Print Connection Info *
[Command]: 1
[Description]: 2020-05-11 15:18:56.810 ERROR [3087] [rtcSetRemoteDescription@245] basic_string::_M_construct null not valid
***************************************************************************************
* 0: Exit / 1: Enter remote description / 2: Enter remote candidate / 3: Send message / 4: Print Connection Info *
[Command]: `
#include <rtc/rtc.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for sleep
#include <ctype.h>
typedef struct {
rtcState state;
rtcGatheringState gatheringState;
int pc;
int dc;
bool connected;
} Peer;
Peer *peer = NULL;
static void descriptionCallback(const char *sdp, const char *type, void *ptr);
static void candidateCallback(const char *cand, const char *mid, void *ptr);
static void stateChangeCallback(rtcState state, void *ptr);
static void gatheringStateCallback(rtcGatheringState state, void *ptr);
static void openCallback(void *ptr);
static void closedCallback(void *ptr);
static void messageCallback(const char *message, int size, void *ptr);
static void deletePeer(Peer *peer);
int all_space(const char *str);
int main(int argc, char **argv){
rtcInitLogger(RTC_LOG_DEBUG);
// Create peer 1
rtcConfiguration config;
memset(&config, 0, sizeof(config));
Peer *peer = (Peer *)malloc(sizeof(Peer));
if (!peer){
printf("Error allocating memory for peer\n");
deletePeer(peer);
}
memset(peer, 0, sizeof(Peer));
printf("Peer created\n");
// Create peer connection
peer->pc = rtcCreatePeerConnection(&config);
rtcSetUserPointer(peer->pc, peer);
rtcSetLocalDescriptionCallback(peer->pc, descriptionCallback);
rtcSetLocalCandidateCallback(peer->pc, candidateCallback);
rtcSetStateChangeCallback(peer->pc, stateChangeCallback);
rtcSetGatheringStateChangeCallback(peer->pc, gatheringStateCallback);
// Since this is the offere, we will create a datachannel
peer->dc = rtcCreateDataChannel(peer->pc, "test");
rtcSetOpenCallback(peer->dc, openCallback);
rtcSetClosedCallback(peer->dc, closedCallback);
rtcSetMessageCallback(peer->dc, messageCallback);
sleep(1);
bool exit = false;
printf("Reached this point\n");
while (!exit) {
printf("\n");
printf("***************************************************************************************\n");
// << endl
printf("* 0: Exit /"
" 1: Enter remote description /"
" 2: Enter remote candidate /"
" 3: Send message /"
" 4: Print Connection Info *\n"
"[Command]: ");
int command = -1;
scanf(" %d", &command);
switch (command) {
case 0: {
exit = true;
break;
}
case 1: {
// Parse Description
printf("[Description]: ");
char *line = NULL;
size_t len = 0;
ssize_t read = 0;
char *sdp = NULL;
while ((read = getline(&line, &len, stdin)) != -1 && !all_space(line)) {
strcat(sdp, line);
strcat(sdp, "\r\n");
}
rtcSetRemoteDescription(peer->pc, sdp, "offer");
break;
}
case 2: {
// Parse Candidate
printf("[Candidate]: ");
char* candidate;
size_t candidate_size = 0;
ssize_t c_read = 0;
if ((c_read = getline(&candidate, &candidate_size, stdin))>=0){
rtcAddRemoteCandidate(peer->pc, candidate, NULL);
}
else{
printf("Error reading line\n");
break;
}
break;
}
case 3: {
// Send Message
if(!peer->connected){
printf("** Channel is not Open **");
break;
}
printf("[Message]: ");
char* message;
size_t message_size = 0;
ssize_t m_read = 0;
if((m_read = getline(&message, &message_size, stdin)) > 0){
rtcSendMessage(peer->dc, message, -1);
}
else {
printf("Error reading line\n");
break;
}
break;
}
case 4: {
// Connection Info
if(!peer->connected){
printf("** Channel is not Open **");
break;
}
char buffer[256];
if (rtcGetLocalAddress(peer->pc, buffer, 256) >= 0)
printf("Local address 1: %s\n", buffer);
if (rtcGetRemoteAddress(peer->pc, buffer, 256) >= 0)
printf("Remote address 1: %s\n", buffer);
else
printf("Could not get Candidate Pair Info\n");
break;
}
default: {
printf("** Invalid Command **");
break;
}
}
}
deletePeer(peer);
return 0;
}
static void descriptionCallback(const char *sdp, const char *type, void *ptr) {
// Peer *peer = (Peer *)ptr;
printf("Description %s:\n%s\n", "offerer", sdp);
printf("Reached this point_descriptioncallback\n");
}
static void candidateCallback(const char *cand, const char *mid, void *ptr) {
// Peer *peer = (Peer *)ptr;
printf("Candidate %s: %s\n", "offerer", cand);
printf("Reached this point_canditateback\n");
}
static void stateChangeCallback(rtcState state, void *ptr) {
Peer *peer = (Peer *)ptr;
peer->state = state;
printf("State %s: %d\n", "offerer", (int)state);
printf("Reached this Statechangecallbackk\n");
}
static void gatheringStateCallback(rtcGatheringState state, void *ptr) {
Peer *peer = (Peer *)ptr;
peer->gatheringState = state;
printf("Gathering state %s: %d\n", "offerer", (int)state);
printf("Reached this gatheringStateCallback\n");
}
static void openCallback(void *ptr) {
Peer *peer = (Peer *)ptr;
peer->connected = true;
printf("Reached this openCallback\n");
// char buffer[256];
// if (rtcGetDataChannelLabel(peer->dc, buffer, 256) >= 0)
// printf("DataChannel %s: Received with label \"%s\"\n","offerer", buffer);
//
}
static void closedCallback(void *ptr) {
Peer *peer = (Peer *)ptr;
peer->connected = false;
printf("Reached this closedCallback\n");
// char buffer[256];
// if (rtcGetDataChannelLabel(peer->dc, buffer, 256) >= 0)
// printf("DataChannel %s: Received with label \"%s\"\n","offerer", buffer);
//
}
static void messageCallback(const char *message, int size, void *ptr) {
// Peer *peer = (Peer *)ptr;
printf("Reached this messageCallback\n");
if (size < 0) { // negative size indicates a null-terminated string
printf("Message %s: %s\n", "offerer", message);
} else {
printf("Message %s: [binary of size %d]\n", "offerer", size);
}
}
static void deletePeer(Peer *peer) {
if (peer) {
if (peer->dc)
rtcDeleteDataChannel(peer->dc);
if (peer->pc)
rtcDeletePeerConnection(peer->pc);
free(peer);
}
}
int all_space(const char *str) {
while (*str) {
if (!isspace(*str++)) {
return 0;
}
}
return 1;
}
from libdatachannel.
@willm Thank you for your PR! I'll have a look shortly.
@stevedanOgochu You issue comes from the NULL
value for the candidate mid. You should put there the actual candidate mid that should be transferred through the signaling. In practice though, it is mostly ignored so an empty string or "0" will work.
from libdatachannel.
It is showing that the error is coming from the remote description(this is the similar function in c++-pc->setRemoteDescription(sdp)), the p2p does not use any signally server right? because you had to manually copy the data to the other side?
[Description]: 2020-05-11 16:51:47.354 ERROR [7803] [rtcSetRemoteDescription@245] basic_string::_M_construct null not valid
from libdatachannel.
Oh sorry I read too fast.
Here is your problem:
char *line = NULL;
size_t len = 0;
ssize_t read = 0;
char *sdp = NULL;
while ((read = getline(&line, &len, stdin)) != -1 && !all_space(line)) {
strcat(sdp, line);
strcat(sdp, "\r\n");
}
rtcSetRemoteDescription(peer->pc, sdp, "offer");
You didn't allocate memory for sdp
, therefore you pass NULL
to rtcSetRemoteDescription
. Also, note that you must free the memory if you make getline allocate internally with line=NULL
.
from libdatachannel.
@willm Thanks for the example! I took the liberty to heavily adapt it to use websockets.
from libdatachannel.
Related Issues (20)
- Websocket::Open crash HOT 3
- Error in build node-datachannel for webtorrent-cli HOT 2
- ABI issue when linking HOT 2
- RtpPacketizationConfig not properly initialized HOT 2
- setLocalDescription's Init parameter may not work. HOT 3
- The push function of the sendQueue in DataChannel will trigger wait and can not be awaked. HOT 3
- Client xxx not found HOT 2
- WebSocket::path() returns nullopt when state is Connecting HOT 2
- Mixed up dynamic and static libjuice dependencies HOT 1
- Source directory requires read/write filesystem during build HOT 3
- C API lacking proper closure support HOT 4
- Lost connectivity after successful connection HOT 7
- WebSocketServer not stopping properly HOT 2
- How to troubleshoot when the onGatheringStateChange function returns very slowly? HOT 1
- Websocket disconnect HOT 2
- Trouble connecting via TURN server HOT 1
- Does libdatachannel support to compile in pure C Linux system(for some embedded device no support C++17)? HOT 3
- rtc::PeerConnection::close() causes the application to crash when called multiple times HOT 1
- Unable to retrieve negotiated media details HOT 2
- crash HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libdatachannel.