libDataChannelPB WebRTC library

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

libDataChannelPB WebRTC library

Post by idle »

libdatachannel is a standalone implementation of WebRTC Data Channels, WebRTC Media Transport, and WebSockets.

WebRTC is a W3C and IETF standard enabling real-time peer-to-peer data and media exchange between two devices.

The security layer is provided by OpenSSL. The WebRTC stack is fully compatible with browsers like Firefox and Chromium
libdatachannel is licensed under MPL 2.0 since version 0.18

The library implements the following communication protocols:

WebRTC Data Channels and Media Transport
WebRTC allows real-time data and media exchange between two devices through a Peer Connection (or RTCPeerConnection), a signaled peer-to-peer connection which can carry both Data Channels and media tracks. It is compatible with browsers Firefox, Chromium, and Safari, and other WebRTC libraries.

Protocol stack:

SCTP-based Data Channels (RFC8831)
SRTP-based Media Transport (RFC8834)
DTLS/UDP (RFC7350 and RFC8261)
ICE (RFC8445) with STUN (RFC8489) and its extension TURN (RFC8656)
Features:

Full IPv6 support (as mandated by RFC8835)
Trickle ICE (RFC8838)
JSEP-compatible session establishment with SDP (RFC8829)
SCTP over DTLS with SDP offer/answer (RFC8841)
DTLS with ECDSA or RSA keys (RFC8827)
SRTP and SRTCP key derivation from DTLS (RFC5764)
Differentiated Services QoS (RFC8837) where possible
Multicast DNS candidates (draft-ietf-rtcweb-mdns-ice-candidates-04)
Multiplexing connections on a single UDP port with libjuice as ICE backend
Note only SDP BUNDLE mode is supported for media multiplexing (RFC8843). The behavior is equivalent to the JSEP bundle-only policy: the library always negotiates one unique network component, where SRTP media streams are multiplexed with SRTCP control packets (RFC5761) and SCTP/DTLS data traffic (RFC8261).

WebSocket
WebSocket is the protocol of choice for WebRTC signaling.

Protocol stack:

WebSocket protocol (RFC6455), client and server side
HTTP over TLS (RFC2818)
Features:

IPv6 and IPv4/IPv6 dual-stack support
Keepalive with ping/pong

PB build Win x64 here pb 6.10
https://github.com/idle-PB/libdatachannelPB

and the source libs examples and docs here
https://github.com/paullouisageneau/libdatachannel

NB: This is a preliminary build as there is a bug in the latest Openssl build on windows x64, so it's linked to an older SSL implementation but it's still ok for native server / clients use.

Only test is the web socket at this stage.

Use cases:
create p2p applications with reliable UDP or TCP connections.

If a stun server is required. There is a linux stun and turn server
https://github.com/paullouisageneau/violet
or maybe you can use freestun
https://freestun.net/
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 627
Joined: Fri Dec 04, 2015 9:26 pm

Re: libDataChannelPB WebRTC library

Post by skinkairewalker »

When trying to run this error occurs.

screenshot : https://prnt.sc/0emFqkUvJdzm
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: libDataChannelPB WebRTC library

Post by idle »

oops just put a comment in it. I'm dyslexic and was trying to indicate that the string is utf8 :|
I reuploaded it thanks

Also there is a linux stun and turn server, if you can't find a public stun server.
https://github.com/paullouisageneau/violet
or you could use
https://freestun.net/
Fred
Administrator
Administrator
Posts: 16619
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: libDataChannelPB WebRTC library

Post by Fred »

Stunning work, thanks !
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 627
Joined: Fri Dec 04, 2015 9:26 pm

Re: libDataChannelPB WebRTC library

Post by skinkairewalker »

Until today I have not been able to understand how these WebRTC datachannels servers work... I don't know the difference between a TurnServer and Signaling Server... or what are the principles related to webrtc...

What would it be like to use libdatachannelpb in practice?

Maybe if I could understand how it works, maybe I could use it with the Construct3 game engine…
:o
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: libDataChannelPB WebRTC library

Post by idle »

if you want to set up p2p connections you need to use a stun server, a turn server (rely server) is rarely needed
Stun needs a public signaling server (like a websocket server on a forwarded port on router or a regular web server to exchange the clients public IP address to establish p2p connections between clients.

So if you ran a public facing websocket server as a signal server you map users IP addresses to some group as "bob" = "xxx.xxx.xxx.xxx", "alice = "yyy.yyy.yyy.yyy" if bob wants to connect to alice, they go to the signal server to get their respective IP addresses and maybe also the address of the stun server, then they open a data channel which gets negotiated via the stun server. It really takes all the hard work out of it.

I don't have the time to do an example at the moment but I don't think it's to hard to do.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: libDataChannelPB WebRTC library

Post by SeregaZ »

i am not get that... i have two programs, that connect to each other. as i found they start web servers and talk with it between of them. i try to capture what they talk. i create server with port, that needed and it receive this header:

Code: Select all

PRI * HTTP/2.0

SM
so it means PB can't work with it? or i come to right place?
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: libDataChannelPB WebRTC library

Post by idle »

No idea without seeing your code.

If you send null terminated strings the reported size is < 0 so in the example it -39

if you pop this in you will see that the message is being sent and received

Code: Select all

ProcedureC messageCallback(ws.l,*pmessage,size.l,*ptr)
	If (size < 0  And CompareMemory(*pmessage,*MESSAGE,MemorySize(*MESSAGE)) <> 0) 
		Debug "WebSocket: Received expected message " + Str(size)
		
		Debug PeekS(*pmessage,-1,#PB_UTF8)
				
	  rtcSendMessage(ws,*pmessage,-1) 
		
		success = #True;
	Else 
		Debug "Received UNEXPECTED message"
		failed = #True;
	EndIf 
EndProcedure 
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: libDataChannelPB WebRTC library

Post by SeregaZ »

that is not my programs. they both start with 127.0.0.1 and work "local". i want to make equalent one of that two. and it have github open source, but that is cpp probably. and probably i found where that place, that i need, but i hope it have some dialog order or Select command to see what it should happen but didnt see it (or just not understand, as always :))

i just see with tcpview program what ports they open. so i made server with same port of second program. then start first program. and that first is see my server and send into it this header "PRI * HTTP/2.0 SM". i think second program should answer for it. so to find what answer is - i create another server with ports from first program, open second program and try to send header with this data... my hope was second program will answer for it. but nope. probably i get wrong data or i make wrong send this header. this HTTP/2.0 is scary me. encryptions or certificates - i am not understand it :( i need some dll? i mean i cant to use standart PB functions to recreate that?

program 2, that wait connection from program 1 and get that header.

Code: Select all

Enumeration
  
  #Server01
  
  #Window
  
  #Editor
  
EndEnumeration

;Port = 24946 ; IDA
Port = 23946 ; GENS

Global EOL$
EOL$ = Chr(13)+Chr(10)

*Buffer = AllocateMemory(10000)

If CreateNetworkServer(#Server01, Port)

  OpenWindow(#Window, 100, 40, 400, 500, "[23946] Gens11 - Genesis : ")
  
  StickyWindow(#Window, 1)
  
  EditorGadget(#Editor, 10, 10, 380, 480)
  
  ;Debug "server starts " + Str(Port)
  AddGadgetItem(#Editor, -1, "server starts " + Str(Port))

  Repeat
    
    ;{ windows repeat
    Repeat
      WEvent = WindowEvent()

      If WEvent = #PB_Event_CloseWindow : Quit = 1 : EndIf
    Until WEvent = 0
    ;}
    
    SEvent = NetworkServerEvent()     
    If SEvent
      ; some event happen
      
      ServerID = EventServer()
      ; what server it was
      
      ClientID = EventClient()
      ; what client it was
  
      Select SEvent
      
        Case 1  ; When a new client has been connected...
          ;Debug "in"
          AddGadgetItem(#Editor, -1, Str(ServerID) + " connection")
          
          
        Case 4  ; When a client has closed the connection...
          ;Debug "*** out"
          AddGadgetItem(#Editor, -1, Str(ServerID) + " disconnection")
          
        Default
          RequestLength = ReceiveNetworkData(ClientID, *Buffer, 2000)
          If RequestLength
            a$ = PeekS(*Buffer, RequestLength, #PB_UTF8)
            AddGadgetItem(#Editor, -1, a$)
          Else
            AddGadgetItem(#Editor, -1, "zero")
          EndIf
          
      EndSelect

    Else
      Delay(20)  ; Don't stole the whole CPU !
    EndIf
    
  Until Quit = 1 
    
  CloseNetworkServer(#Server01)
Else
  MessageRequester(AtomicTitle$, "Error: can't create the server (port in use ?).", 0)
EndIf
  
End 
 
haaaa! it looks like second program is answer! but i just cant get that... or it send to wrong place. or my mistake with Send data. by some reason second program and my emulator have same port. but when i see how work original programs - they have different ports

Code: Select all


Enumeration
  
  #Server01
  
  #Window
  
  #Editor
  
  #Button
  
EndEnumeration

Port = 24946 ; IDA
;Port = 23946 ; GENS

Global EOL$
EOL$ = Chr(13)+Chr(10)

*Buffer = AllocateMemory(10000)

*SendBuffer = AllocateMemory(200)
Length = *SendBuffer
Length + PokeS(Length, "PRI * HTTP/2.0" + EOL$, -1, #PB_UTF8)  
Length + PokeS(Length, ""               + EOL$, -1, #PB_UTF8)  
Length + PokeS(Length, "SM"             + EOL$, -1, #PB_UTF8)  
Length + PokeS(Length, ""               + EOL$, -1, #PB_UTF8)   
;Length + PokeS(Length, ""               + EOL$, -1, #PB_UTF8) 
Length + PokeS(Length, #CRLF$, -1, #PB_UTF8) 

test$ = PeekS(*SendBuffer, Length - *SendBuffer, #PB_UTF8) ;: Debug test$

If CreateNetworkServer(#Server01, Port)

  OpenWindow(#Window, 100, 40, 400, 300, "IDA")
  
  StickyWindow(#Window, 1)
  
  EditorGadget(#Editor, 10, 10, 380, 240)
  
  ButtonGadget(#Button, 10, 260, 100, 20, "send header")
  
  ;Debug "server starts " + Str(Port)
  AddGadgetItem(#Editor, -1, "server starts " + Str(Port))

  Repeat
    
    ;{ windows repeat
    Repeat
      WEvent = WindowEvent()
      
      Select WEvent
          
        Case #PB_Event_Gadget
          Select EventGadget()
                        
            Case #Button
              ; i should send
              ;PRI * HTTP/2.0
              ;
              ;SM
              ;
              
              ConnectionID = OpenNetworkConnection("127.0.0.1", 23946) ; to Gens
              If ConnectionID
                AddGadgetItem(#Editor, -1, "have connection for send")                
                
                sendresult = SendNetworkData(ConnectionID, *SendBuffer, Length - *SendBuffer)
                
                AddGadgetItem(#Editor, -1, "result of sending " + Str(sendresult))

                ;CloseNetworkConnection(ConnectionID)
              Else
                ;MessageRequester("PureBasic - Client", "Can't find the server (Is it launched ?).", 0)
                AddGadgetItem(#Editor, -1, "probably server is not work")
              EndIf
              
              
          EndSelect
          
        Case #PB_Event_CloseWindow
          Quit = 1
         
          
      EndSelect

    Until WEvent = 0
    ;}
    
    SEvent = NetworkServerEvent()     
    If SEvent
      ; some event happen
      
      ServerID = EventServer()
      ; what server it was
      
      ClientID = EventClient()
      ; what client it was
  
      Select SEvent
      
        Case 1  ; When a new client has been connected...
          ;Debug "in"
          AddGadgetItem(#Editor, -1, Str(ServerID) + " connection")
          
          
        Case 4  ; When a client has closed the connection...
          ;Debug "*** out"
          AddGadgetItem(#Editor, -1, Str(ServerID) + " disconnection")
          
        Default
          RequestLength = ReceiveNetworkData(ClientID, *Buffer, 2000)
          If RequestLength
            a$ = PeekS(*Buffer, RequestLength, #PB_UTF8)
            AddGadgetItem(#Editor, -1, a$)
          Else
            AddGadgetItem(#Editor, -1, "zero")
          EndIf
          
      EndSelect

    Else
      Delay(20)  ; Don't stole the whole CPU !
    EndIf
    
  Until Quit = 1 
    
  CloseNetworkServer(#Server01)
Else
  MessageRequester(AtomicTitle$, "Error: can't create the server (port in use ?).", 0)
EndIf
  
End  

User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: libDataChannelPB WebRTC library

Post by idle »

What has that got to do with libdatachannel?
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: libDataChannelPB WebRTC library

Post by SeregaZ »

i just google PRI * HTTP/2.0 SM and it brings me here.

from here: https://www.purebasic.fr/english/viewto ... 04#p614204

i am come to wrong place?
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: libDataChannelPB WebRTC library

Post by idle »

Asking in codding questions would be more appropriate if your not using libdatachannel.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: libDataChannelPB WebRTC library

Post by SeregaZ »

i just to want understand that is case, where i need use it or it can be done by standart PB functions? this header, that i capture is bad and i need all of that libdatachannel, or i can use usual functions of PB for it?
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: libDataChannelPB WebRTC library

Post by idle »

if you want websockets you can use libdatachannel but it's only built for windows x64 at the moment.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: libDataChannelPB WebRTC library

Post by infratec »

For WebSockets you can also use the code from dadido3

https://www.purebasic.fr/english/viewtopic.php?p=592179

It is crosspaltform and PB only.

If you need it secured, you can use the libssl stuff by HexOr. Maybe.
Post Reply