Page 1 of 2

libDataChannelPB WebRTC library

Posted: Sat Jan 06, 2024 10:55 pm
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/

Re: libDataChannelPB WebRTC library

Posted: Sun Jan 07, 2024 5:02 pm
by skinkairewalker
When trying to run this error occurs.

screenshot : https://prnt.sc/0emFqkUvJdzm

Re: libDataChannelPB WebRTC library

Posted: Sun Jan 07, 2024 6:51 pm
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/

Re: libDataChannelPB WebRTC library

Posted: Tue Jan 09, 2024 10:33 am
by Fred
Stunning work, thanks !

Re: libDataChannelPB WebRTC library

Posted: Mon Jan 15, 2024 5:02 am
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

Re: libDataChannelPB WebRTC library

Posted: Mon Jan 15, 2024 9:11 am
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.

Re: libDataChannelPB WebRTC library

Posted: Fri Feb 16, 2024 2:50 pm
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?

Re: libDataChannelPB WebRTC library

Posted: Fri Feb 16, 2024 7:55 pm
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 

Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 1:07 am
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  


Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 1:35 am
by idle
What has that got to do with libdatachannel?

Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 1:48 am
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?

Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 1:55 am
by idle
Asking in codding questions would be more appropriate if your not using libdatachannel.

Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 2:08 am
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?

Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 2:27 am
by idle
if you want websockets you can use libdatachannel but it's only built for windows x64 at the moment.

Re: libDataChannelPB WebRTC library

Posted: Sat Feb 17, 2024 10:48 am
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.