# P2pStreamsChannel Allow to setup one-to-many P2P stream connections ([WebRTC](https://webrtc.org/)) between clients through Rails server (ActionCable) as the signaling server. ## Work Flow ``` =================================== Connect to Signaling Server (Rails) =================================== host-user -------------------------------------> Rails server host-user <-----views/chat_room----------------- Rails server (session: chat_room, peer_id: host_user) host-user ---turbo-connect-stream--------------> Rails server/ActionCable client-user -----------------------------------> Rails server client-user <-----views/chat_room--------------- Rails server (session: chat_room, peer_id: client_user) client-user ---turbo-connect-stream------------> Rails server/ActionCable ... other clients ... =========== Negotiation =========== host-user ------SessionReady--> Rails Server --> client-user client-user ----SessionReady--> Rails Server --> host-user host-user --setupRTCPeerConnection --+ <-----------------------------+ host-user ------SdpOffer -----> Rails Server --> client-user client-user --setupRTCPeerConnection --+ <------------------------------+ client-user ----SdpAnswer ----> Rails Server --> host-user iceServers --ice-candidate----> host-user ----> client-user iceServers --ice-candidate----> client-user --> host-user ========= Connected ========= After client-user connected to the host-user, all of them will disconnected to the signaling server (in order to save memory and other things), only the host-user keep connect to Rails server. In case you want keep client connection, you could set params `keepCableConnection: true` to the p2p-frame. client-user1 ----X disconnect from -----> Rails server Action cable client-user2 ----X disconnect from -----> Rails server Action cable ... host-user <-------keep connect to ------> Rails server Action cable This is one-to-many p2p connections: client-user1 --- send message 'hi' ---> host-user host-user --- send message {user1: 'hi'} to --> others ============ Disconnected ============ client-user1 ---X disconnect ---> host-user host-user ---> send client-user1 status ---> others client-user1 ----reload --------> Rails server host-user <--- start re-negotiating through Rails server ----> client-user1 host-user ---X disconnect ---> Rails server all client-users will be disconnected the first client-user re-connect to Rails server will become the new host and start work-flow again ``` ## Installation ```ruby $ gem "p2p_streams_channel" $ bundle isntall $ rails g p2p_streams_channel:install ``` ## Usage Create a Stimulus P2pController in which you will receive other p2p-connections status, data send by other connected connections, and send your data to others. ```ruby $ rails g p2p_streams_channel:controller chat # it will create js file `app/javascript/controllers/chat_controller.js` ``` Render a p2p-frame-tag ```ruby # views/chat_rooms/_chat_room.html.erb <%= p2p_frame_tag( session_id: dom_id(chat_room), peer_id: dom_id(current_user), # config: { # ice_servers: [ # { urls: ["stun:stun.l.google.com:19302", "stun:stun1.l.google.com:19302", "stun:stun2.l.google.com:19302"] }, # ], # heartbeat: { # interval_mls: 100, # idle_timeout_mls: 200 # }, # keepCableConnection: false # } ) do %>