HyperCrowd / moba

Quick MOBA Concept using Phaser.js
0 stars 0 forks source link

Add Multiplayer Support #2

Open HyperCrowd opened 6 days ago

HyperCrowd commented 6 days ago
HyperCrowd commented 6 days ago

https://www.metered.ca/tools/openrelay/

var peerConfiguration = {};

(async() => {
  const response = await fetch("https://yourappname.metered.live/api/v1/turn/credentials?apiKey=API_KEY");
  const iceServers = await response.json();
  peerConfiguration.iceServers = iceServers
})();

var myPeerConnection = new RTCPeerConnection(peerConfiguration);

let configuration = {
  'iceServers': [{
    'urls': 'stun:stun.l.google.com:19302'
  }]
};

let peerConnection = new RTCPeerConnection(configuration);

peerConnection.createOffer()
  .then(offer => peerConnection.setLocalDescription(offer))
  .then(() => {
    // Send the offer to the remote peer using your signaling server
  });

peerConnection.onicecandidate = event => {
  if (event.candidate) {
    // Send the ICE candidate to the remote peer using your signaling server
  }
};

// Listen for messages from your signaling server
signalingServer.onmessage = message => {
  if (message.offer) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
    // Create an answer and send it back to the remote peer
    peerConnection.createAnswer()
      .then(answer => peerConnection.setLocalDescription(answer))
      .then(() => {
        // Send the answer back to the remote peer using your signaling server
      });
  } else if (message.answer) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(message.answer));
  } else if (message.iceCandidate) {
    peerConnection.addIceCandidate(new RTCIceCandidate(message.iceCandidate));
  }
};

var myPeerConnection = new RTCPeerConnection({
  iceServers: [
    {
      urls: "stun:openrelay.metered.ca:80",
    },
    {
      urls: "turn:openrelay.metered.ca:80",
      username: "openrelayproject",
      credential: "openrelayproject",
    },
    {
      urls: "turn:openrelay.metered.ca:443",
      username: "openrelayproject",
      credential: "openrelayproject",
    },
    {
      urls: "turn:openrelay.metered.ca:443?transport=tcp",
      username: "openrelayproject",
      credential: "openrelayproject",
    },
  ],
});

const iceConfiguration = {
    iceServers: [
        {
            urls: 'turn:demo-turn-server.test.com:19403',
            username: 'optional',
            credentials: 'auth-token'
        }
    ]
}

const peerConnection = new RTCPeerConnection(iceConfiguration);

let peerConnectionA;
let peerConnectionB;
let dataChannelA;
let dataChannelB;

const configuration = {
    iceServers: [
       {
        urls: "stun:stun.relay.metered.ca:80"
       }, 
       {
            urls: "turn:standard.relay.metered.ca:80",
            username: "",
            credential: "",
        },
    ],
};

peerConnectionA = new RTCPeerConnection(configuration);
peerConnectionB = new RTCPeerConnection(configuration);

// Create DataChannel on peer A and listen for it on peer B
dataChannelA = peerConnectionA.createDataChannel("chat");
setupDataChannel(dataChannelA, 'A');

peerConnectionB.ondatachannel = (event) => {
    dataChannelB = event.channel;
    setupDataChannel(dataChannelB, 'B');
};

function setupDataChannel(channel, user) {
    channel.onopen = () => console.log(`Data channel for ${user} is open`);
    channel.onmessage = (event) => receiveMessage(user, event.data);
}

peerConnectionA.onicecandidate = (event) => {
    if (event.candidate) {
        peerConnectionB.addIceCandidate(event.candidate);
    }
};
peerConnectionB.onicecandidate = (event) => {
    if (event.candidate) {
        peerConnectionA.addIceCandidate(event.candidate);
    }
};

// Create an offer from peer A and set up the connection
// this triggers the 
const offer = await peerConnectionA.createOffer();
await peerConnectionA.setLocalDescription(offer);
await peerConnectionB.setRemoteDescription(offer);

const answer = await peerConnectionB.createAnswer();
await peerConnectionB.setLocalDescription(answer);
await peerConnectionA.setRemoteDescription(answer);
        let peerConnectionA;
        let peerConnectionB;
        let dataChannelA;
        let dataChannelB;

        const configuration = {
            iceServers: []
        };

        async function initWebRTC() {
            peerConnectionA = new RTCPeerConnection(configuration);
            peerConnectionB = new RTCPeerConnection(configuration);

            // Set up data channel on Peer A
            dataChannelA = peerConnectionA.createDataChannel("chat");
            setupDataChannel(dataChannelA, 'A');

            // Receive data channel on Peer B
            peerConnectionB.ondatachannel = (event) => {
                dataChannelB = event.channel;
                setupDataChannel(dataChannelB, 'B');
            };

            // Exchange ICE candidates
            peerConnectionA.onicecandidate = (event) => {
                if (event.candidate) {
                    peerConnectionB.addIceCandidate(event.candidate);
                }
            };
            peerConnectionB.onicecandidate = (event) => {
                if (event.candidate) {
                    peerConnectionA.addIceCandidate(event.candidate);
                }
            };

            // Create offer from A and set local/remote descriptions
            const offer = await peerConnectionA.createOffer();
            await peerConnectionA.setLocalDescription(offer);
            await peerConnectionB.setRemoteDescription(offer);

            // Create answer from B and set local/remote descriptions
            const answer = await peerConnectionB.createAnswer();
            await peerConnectionB.setLocalDescription(answer);
            await peerConnectionA.setRemoteDescription(answer);
        }

        function setupDataChannel(channel, localUser) {
            channel.onopen = () => console.log(`Data channel for ${localUser} is open`);
            channel.onmessage = (event) => receiveMessage(localUser, event.data);
        }

        function sendMessage(user) {
            const input = document.getElementById(`input${user}`);
            const message = input.value;
            if (message) {
                const data = JSON.stringify({ user, message });
                if (user === 'A' && dataChannelA && dataChannelA.readyState === "open") {
                    dataChannelA.send(data);
                    displayMessage(user, `${user}: ${message}`);
                    input.value = '';
                } else if (user === 'B' && dataChannelB && dataChannelB.readyState === "open") {
                    dataChannelB.send(data);
                    displayMessage(user, `${user}: ${message}`);
                    input.value = '';
                }
            }
        }

        function receiveMessage(localUser, data) {
            const { user: fromUser, message } = JSON.parse(data);
            displayMessage(localUser, `${fromUser}: ${message}`);
        }

        function displayMessage(user, message) {
            const messagesDiv = document.getElementById(`messages${user}`);
            const messageElement = document.createElement('p');
            messageElement.textContent = message;
            messagesDiv.appendChild(messageElement);
            messagesDiv.scrollTop = messagesDiv.scrollHeight;
        }

        initWebRTC();

Testing: https://www.metered.ca/turn-server-testing

HyperCrowd commented 6 days ago

https://dashboard.metered.ca/turnserver/app/67158892c03aff10cd7b7923

HyperCrowd commented 6 days ago

https://www.youtube.com/watch?v=PLmauY3ky4g