Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Question I want to give data to Broadcast.scene through WebSocket

Discussion in 'Unity Render Streaming' started by chealin, Nov 16, 2022.

  1. chealin

    chealin

    Joined:
    Sep 10, 2017
    Posts:
    76
    I want to give data to Broadcast.scene through WebSocket

    I downloaded the WebApp

    Fixed WebApp-build-websocket.js.
    But when I build the code comes back

    I want to give data to Brodcast.scene but I don't know where to modify the code


    Is there any way to give data (string) to Broadcast.scene using WebSocket?

    --
    Code (CSharp):
    1. using UnityEngine;
    2. using WebSocketSharp;
    3. using Unity.RenderStreaming;
    4.  
    5.  
    6.  
    7. public class WsClient : MonoBehaviour
    8. {
    9.    
    10.     WebSocket ws;
    11.  
    12.     public void StartWsClient(string url)
    13.     {
    14.  
    15.        url = "ws://" + url;
    16.  
    17.         Debug.Log("Connect WS url...." + url);
    18.  
    19.         try {
    20.             ws = new WebSocket(url);
    21.             ws.Connect();
    22.  
    23.             Debug.Log("WS STATUS ::::: " + ws.ReadyState.ToString());
    24.  
    25.             ws.OnMessage += Recv;
    26.             ws.OnClose += CloseConnect;
    27.  
    28.         }
    29.         catch(System.Exception ex)
    30.         {
    31.             Debug.Log("Connect WS :::: " + ex.ToString());
    32.         }
    33.     }
    34.  
    35.  
    36.     public void Recv(object sender, MessageEventArgs e)
    37.     {
    38.         Debug.Log("WEBSOCKET CLINET Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
    39.  
    40.         var routedMessage = JsonUtility.FromJson<RoutedMessage<SignalingMessage>>(e.Data.ToString());
    41.  
    42.         SignalingMessage msg;
    43.         if (!string.IsNullOrEmpty(routedMessage.type))
    44.         {
    45.             msg = routedMessage.data;
    46.         }
    47.         else
    48.         {
    49.             msg = JsonUtility.FromJson<SignalingMessage>(e.Data.ToString());
    50.         }
    51.  
    52.         if (routedMessage.type == "offer")
    53.         {
    54.             Controller.Inst.requestManager.ReceiveData(msg.sdp.ToString());
    55.         }
    56.  
    57.         if (routedMessage.type == "answer")
    58.         {
    59.             Debug.Log("MSG:" + msg.sdp.ToString());
    60.             Controller.Inst.requestManager.ReceiveData(msg.sdp.ToString());
    61.         }
    62.     }
    63.  
    64.     public void CloseConnect(object sender, CloseEventArgs e)
    65.     {
    66.         DisConnectServer();
    67.     }
    68.     public void DisConnectServer()
    69.     {
    70.         try
    71.         {
    72.             if (ws == null)
    73.             {
    74.                 return;
    75.             }
    76.  
    77.             if (ws.IsAlive)
    78.             {
    79.                 ws.Close();
    80.             }
    81.         }
    82.         catch (System.Exception e)
    83.         {
    84.        
    85.         }
    86.     }
    87.  
    88.  
    89.     private void Update()
    90.     {
    91.         if (ws.ReadyState != WebSocketState.Open)
    92.         {
    93.             return;
    94.         }
    95.  
    96.         if (Input.GetKeyDown(KeyCode.Y))
    97.         {
    98.             Debug.Log("STATE : "+ws.ReadyState);
    99.            
    100.  
    101.             ws.Send("{    \"type\":\"answer\",   \"from\":\"9f521130-a061-4237-8e0e-84388521d75c\", \"to\":\"9f521130-a061-4237-8e0e-84388521d75c\",   \"data\":{       \"sdp\":\"SetColor|Bottle|#FFBC42\"   } }");
    102.            
    103.  
    104.         }
    105.  
    106.     }
    107. }
    108.  
    109.  
    --
    upload_2022-11-16_18-10-24.png
     
  2. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
    Even if you do not modify it, if it is the same connectionId, it should be sent to the other ws.
     
  3. chealin

    chealin

    Joined:
    Sep 10, 2017
    Posts:
    76
    that means
    Are you saying that I have to create a new ws?

    I've modified the code in WebApp-scr-index.ts
    (I wanted to modify WebApp-build-index.js, but every time I build the WebApp, the code I wrote gets deleted.)
    [Code added to index.ts]
    Code (JavaScript):
    1.  
    2. const WebSocket = require('ws');
    3. const wss = new WebSocket.Server({ port: 9091 },()=>{
    4.     console.log('server started');
    5. });
    6. wss.on('connection', function connection(myws) {
    7.   myws.on('message', (data) => {
    8.       console.log('data received \n %o',data.toString());
    9.       myws.send(data.toString());
    10.    });
    11. });
    12. wss.on('listening',()=>{
    13.    console.log('listening on 9091');
    14. });


    And I have modified the code to untiy
    Code (CSharp):
    1. using UnityEngine;
    2. using WebSocketSharp;
    3. using Unity.RenderStreaming;
    4.  
    5.  
    6.  
    7. public class WsClient : MonoBehaviour
    8. {
    9.    
    10.     WebSocket ws;
    11.  
    12.     public void StartWsClient(string url)
    13.     {
    14.  
    15.         url = url.Replace(":9090","");
    16.  
    17.        url = "ws://" + url+":9091";
    18.  
    19.         Debug.Log("Connect WS url...." + url);
    20.  
    21.         try {
    22.             ws = new WebSocket(url);
    23.             ws.Connect();
    24.  
    25.             Debug.Log("WS STATUS ::::: " + ws.ReadyState.ToString());
    26.  
    27.             ws.OnMessage += Recv;
    28.             ws.OnClose += CloseConnect;
    29.  
    30.         }
    31.         catch(System.Exception ex)
    32.         {
    33.             Debug.Log("Connect WS :::: " + ex.ToString());
    34.         }
    35.     }
    36.  
    37.  
    38.     public void Recv(object sender, MessageEventArgs e)
    39.     {
    40.         //Debug.Log("WEBSOCKET CLINET Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
    41.  
    42.         string eData = e.Data;
    43.         Debug.Log(eData);
    44.      
    45.         Debug.Log("WEBSOCKET CLINET Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
    46.  
    47.  
    48.     }
    49.  
    50.     public void CloseConnect(object sender, CloseEventArgs e)
    51.     {
    52.         DisConnectServer();
    53.     }
    54.     public void DisConnectServer()
    55.         {
    56.             try
    57.             {
    58.                 if (ws == null)
    59.             {
    60.                 return;
    61.             }
    62.  
    63.             if (ws.IsAlive)
    64.             {
    65.                 ws.Close();
    66.             }
    67.         }
    68.         catch (System.Exception e)
    69.         {
    70.        
    71.         }
    72.     }
    73.  
    74.  
    75.     private void Update()
    76.     {
    77.         if (ws.ReadyState != WebSocketState.Open)
    78.         {
    79.             return;
    80.         }
    81.  
    82.         if (Input.GetKeyDown(KeyCode.Y))
    83.         {
    84.             Debug.Log("STATE : "+ws.ReadyState);
    85.  
    86.  
    87.             //ws.Send("{    \"type\":\"answer\",   \"from\":\"9f521130-a061-4237-8e0e-84388521d75c\", \"to\":\"9f521130-a061-4237-8e0e-84388521d75c\",   \"data\":{       \"sdp\":\"SetColor|Bottle|#FFBC42\"   } }");
    88.             ws.Send("SetColor|Bottle|#FFBC42");
    89.  
    90.         }
    91.  
    92.     }
    93. }
    94.  
    95.  
    code to run
    It works when I do the above

    Is it correct to write like this?
     

    Attached Files:

    Last edited: Nov 17, 2022
  4. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
  5. chealin

    chealin

    Joined:
    Sep 10, 2017
    Posts:
    76
    Yes, that's right

    I used the Github link-WebApp part from the documentation.
    Documentation: https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/customize-webapp.html
    Used WebApp github: https://github.com/Unity-Technologies/UnityRenderStreaming/tree/develop/WebApp


    I did npm build before creating the web application.
    I found out while writing this answer
    The Build folder I modified looks like a folder that I created while running npm build...
    I knew I was trying to fix it in the wrong place.

    ---What I would like to do
    I create a button in index.html and when the button is clicked
    I want String value to be passed to Unity through WebSocket.

    -
    I don't know how to access from html to that index.ts
    (Reason for access: Because the WebSocket code I wrote is in index.ts.)

    I want to put the WebSocket code in WebApp-Client-public-receiver-js-main.js
    I tried but it didn't work.

    Do I need to import anything else to WebApp-Client-public-receiver-js-main.js?
     
  6. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    288
    Start your WebApp with the --private flag.
    After that, connect the paired Unity.exe / Browser to the WebApp with the same ConnectionId. Then in the WebApp with the same ConnectionId
    When Pair is generated and Unity.exe sends offer to WebApp, offer is sent to Browser.
     
  7. chealin

    chealin

    Joined:
    Sep 10, 2017
    Posts:
    76
    hello

    When I press the keyboard in Unity
    I wrote a code that sends the data received from HTML back to Unity, and the operation succeeded.

    But I need a way to send data to Unity when a button is pressed on the Web.

    I want to write WebSocket code in WebApp-Client-public-receiver-js-main.js
    If you write the WebSocket code in main.js, the separately written WebSocket does not work.

    Do you know how to make it work when you put WebSocket in [WebApp-Client-public-receiver-js-main.js]?

    Thank you for always giving good answers.

    [MY Main.js Code]
    At the bottom of main.js is the WebSocket code I wrote.

    Code (CSharp):
    1. import { getServerConfig, getRTCConfiguration } from "../../js/config.js";
    2. import { createDisplayStringArray } from "../../js/stats.js";
    3. import { VideoPlayer } from "../../js/videoplayer.js";
    4. import { RenderStreaming } from "../../module/renderstreaming.js";
    5. import { Signaling, WebSocketSignaling } from "../../module/signaling.js";
    6.  
    7.  
    8. /** @type {Element} */
    9. let playButton;
    10. /** @type {RenderStreaming} */
    11. let renderstreaming;
    12. /** @type {boolean} */
    13. let useWebSocket;
    14.  
    15. const codecPreferences = document.getElementById('codecPreferences');
    16. const supportsSetCodecPreferences = window.RTCRtpTransceiver &&
    17.   'setCodecPreferences' in window.RTCRtpTransceiver.prototype;
    18. const messageDiv = document.getElementById('message');
    19. messageDiv.style.display = 'none';
    20.  
    21. const playerDiv = document.getElementById('player');
    22. const lockMouseCheck = document.getElementById('lockMouseCheck');
    23. const videoPlayer = new VideoPlayer();
    24.  
    25. setup();
    26.  
    27. window.document.oncontextmenu = function () {
    28.   return false;     // cancel default menu
    29. };
    30.  
    31. window.addEventListener('resize', function () {
    32.   videoPlayer.resizeVideo();
    33. }, true);
    34.  
    35. window.addEventListener('beforeunload', async () => {
    36.   if(!renderstreaming)
    37.     return;
    38.   await renderstreaming.stop();
    39. }, true);
    40.  
    41. async function setup() {
    42.   const res = await getServerConfig();
    43.   useWebSocket = res.useWebSocket;
    44.   showWarningIfNeeded(res.startupMode);
    45.   showCodecSelect();
    46.   showPlayButton();
    47. }
    48.  
    49.  
    50.  
    51. function showWarningIfNeeded(startupMode) {
    52.   const warningDiv = document.getElementById("warning");
    53.   if (startupMode == "private") {
    54.     warningDiv.innerHTML = "<h4>Warning</h4> This sample is not working on Private Mode.";
    55.     warningDiv.hidden = false;
    56.   }
    57. }
    58.  
    59. function showPlayButton() {
    60.   if (!document.getElementById('playButton')) {
    61.     const elementPlayButton = document.createElement('img');
    62.     elementPlayButton.id = 'playButton';
    63.     elementPlayButton.src = '../../images/Play.png';
    64.     elementPlayButton.alt = 'Start Streaming';
    65.     playButton = document.getElementById('player').appendChild(elementPlayButton);
    66.     playButton.addEventListener('click', onClickPlayButton);
    67.   }
    68. }
    69.  
    70. function onClickPlayButton() {
    71.   playButton.style.display = 'none';
    72.  
    73.   // add video player
    74.   videoPlayer.createPlayer(playerDiv, lockMouseCheck);
    75.   setupRenderStreaming();
    76. }
    77.  
    78. async function setupRenderStreaming() {
    79.   codecPreferences.disabled = true;
    80.  
    81.   const signaling = useWebSocket ? new WebSocketSignaling() : new Signaling();
    82.   const config = getRTCConfiguration();
    83.   renderstreaming = new RenderStreaming(signaling, config);
    84.   renderstreaming.onConnect = onConnect;
    85.   renderstreaming.onDisconnect = onDisconnect;
    86.   renderstreaming.onTrackEvent = (data) => videoPlayer.addTrack(data.track);
    87.   renderstreaming.onGotOffer = setCodecPreferences;
    88.  
    89.   await renderstreaming.start();
    90.  
    91. let myConnectID =document.getElementById('myConnectId').value;//My Custom ConnectId
    92.   await renderstreaming.createConnection(myConnectID);
    93. }
    94.  
    95. function onConnect() {
    96.   const channel = renderstreaming.createDataChannel("input");
    97.   videoPlayer.setupInput(channel);
    98.   showStatsMessage();
    99. }
    100.  
    101. async function onDisconnect(connectionId) {
    102.   clearStatsMessage();
    103.   messageDiv.style.display = 'block';
    104.   messageDiv.innerText = `Disconnect peer on ${connectionId}.`;
    105.  
    106.   await renderstreaming.stop();
    107.   renderstreaming = null;
    108.   videoPlayer.deletePlayer();
    109.   if (supportsSetCodecPreferences) {
    110.     codecPreferences.disabled = false;
    111.   }
    112.   showPlayButton();
    113. }
    114.  
    115.  
    116.  
    117. function setCodecPreferences() {
    118.   /** @type {RTCRtpCodecCapability[] | null} */
    119.   let selectedCodecs = null;
    120.   if (supportsSetCodecPreferences) {
    121.     codecPreferences.selectedIndex = 9;//추가
    122.     const preferredCodec = codecPreferences.options[codecPreferences.selectedIndex];
    123.     if (preferredCodec.value !== '') {
    124.       const [mimeType, sdpFmtpLine] = preferredCodec.value.split(' ');
    125.       const { codecs } = RTCRtpSender.getCapabilities('video');
    126.       const selectedCodecIndex = codecs.findIndex(c => c.mimeType === mimeType && c.sdpFmtpLine === sdpFmtpLine);
    127.       const selectCodec = codecs[selectedCodecIndex];
    128.       selectedCodecs = [selectCodec];
    129.     }
    130.   }
    131.  
    132.   if (selectedCodecs == null) {
    133.     return;
    134.   }
    135.   const transceivers = renderstreaming.getTransceivers().filter(t => t.receiver.track.kind == "video");
    136.   if (transceivers && transceivers.length > 0) {
    137.     transceivers.forEach(t => t.setCodecPreferences(selectedCodecs));
    138.   }
    139. }
    140.  
    141. function showCodecSelect() {
    142.   if (!supportsSetCodecPreferences) {
    143.     messageDiv.style.display = 'block';
    144.     messageDiv.innerHTML = `Current Browser does not support <a href="https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpTransceiver/setCodecPreferences">RTCRtpTransceiver.setCodecPreferences</a>.`;
    145.     return;
    146.   }
    147.  
    148.   const codecs = RTCRtpSender.getCapabilities('video').codecs;
    149.   codecs.forEach(codec => {
    150.     if (['video/red', 'video/ulpfec', 'video/rtx'].includes(codec.mimeType)) {
    151.       return;
    152.     }
    153.     const option = document.createElement('option');
    154.     option.value = (codec.mimeType + ' ' + (codec.sdpFmtpLine || '')).trim();
    155.     option.innerText = option.value;
    156.     codecPreferences.appendChild(option);
    157.   });
    158.   codecPreferences.disabled = false;
    159. }
    160.  
    161. /** @type {RTCStatsReport} */
    162. let lastStats;
    163. /** @type {number} */
    164. let intervalId;
    165.  
    166. function showStatsMessage() {
    167.   intervalId = setInterval(async () => {
    168.     if (renderstreaming == null) {
    169.       return;
    170.     }
    171.  
    172.     const stats = await renderstreaming.getStats();
    173.     if (stats == null) {
    174.       return;
    175.     }
    176.  
    177.     const array = createDisplayStringArray(stats, lastStats);
    178.     if (array.length) {
    179.       messageDiv.style.display = 'block';
    180.       messageDiv.innerHTML = array.join('<br>');
    181.     }
    182.     lastStats = stats;
    183.   }, 1000);
    184. }
    185.  
    186. function clearStatsMessage() {
    187.   if (intervalId) {
    188.     clearInterval(intervalId);
    189.   }
    190.   lastStats = null;
    191.   intervalId = null;
    192.   messageDiv.style.display = 'none';
    193.   messageDiv.innerHTML = '';
    194. }
    195.  
    196. //Add My Custom Code
    197. const WebSocket = require('ws');
    198. const wss = new WebSocket.Server({ port: 9091 },()=>{
    199.     console.log('server started');
    200. });
    201.  
    202. wss.on('connection', function connection(myws) {
    203.   myws.on('message', (data) => {
    204.       console.log('data received \n %o',data.toString());
    205.       myws.send(data.toString());
    206.    });
    207. });
    208.  
    209. wss.on('listening',()=>{
    210.    console.log('listening on 9091');
    211. });
    upload_2022-11-21_11-50-47.png

    upload_2022-11-21_11-47-25.png
     
  8. kazuki_unity729

    kazuki_unity729

    Unity Technologies

    Joined:
    Aug 2, 2018
    Posts:
    803
    @chealin
    I would like to know your question accurately, I guess your question is how to use the WebSocket on Unity.
     
  9. chealin

    chealin

    Joined:
    Sep 10, 2017
    Posts:
    76
    hello

    Yes, that's right

    I got a kind answer on how to pass value to WebSocket in Unity

    Sorry I posted another question in the same question session. I'll ask again.
    thank you