This example provides a structured way to establish and manage a WebSocket connection and perform various operations using that connection, including request-response interactions and subscription to channels.
First, we need to establish a connection with the WebSocket. Then we created handlers for whether when a WebSocket connection is established successfully or not. We also created handlers for the Buttons that get/sets a data as well as the subscribing/unsubscribing from a channel.
Once the User Subscribed, he can then trigger notifications on the WebSocket clients.
Unreal Engine Blueprint
The Type/Message can be anything, determined entirely by the user. Both of them are represented as strings.
In the send data, we exposed our internal Data Json Serializer, which allows user to send data in the form of a JSON string, supporting various data structures.
letws:WebSocket=null;connect.onClick=()=>{if(ws&&ws.readyState!==WebSocket.CLOSED)ws.close();ws=null;ws=newWebSocket(`ws://${address.value.trim()}:5000`);ws.onopen=onConnected;ws.onclose=()=>onDisconnected();ws.onerror=()=>onDisconnected()ws.onmessage=onMessage;}functiononConnected(){address.disabled=true;connect.disabled=true;status.title='Connected';status.type='success';}functiononDisconnected(error?:string){address.disabled=false;connect.disabled=false;status.title=error??'Disconnected';status.type='error';}letmessage=0;typeWSRequest={resolve:(response:any)=>void,reject:(error:string)=>void};constrequests:Record<number,WSRequest>={};functiononMessage(e:MessageEvent<string>){console.log("GOT",e.data);constobj=JSON.parse(e.data);if(obj.id){constpending=requests[obj.id];if(!pending)return;if(obj.status!==200)returnpending.reject(`Failed to process WS request, error: ${obj.status}`);pending.resolve(obj.body);}if(obj.channel){switch(obj.type){case'Data':Alert.info('UE Sent JSON Data');payload.value=obj.message;constjson=JSON.parse(obj.message);console.log('GOT Json Data',json)break;case'Message':Alert.info(`UE Sent: ${obj.message}`);break;}}}functionwsRequest(method:'GET'|'POST',url:string,body?:any):Promise<string>{if(ws?.readyState!==WebSocket.OPEN)returnPromise.reject('WebSocket is not connected');returnnewPromise((resolve,reject)=>{constid=message++;requests[id]={resolve,reject};ws.send(JSON.stringify({method,url,body,id}));})}btnGet.onClick=async()=>{try{constres=awaitwsRequest('GET','/api/control');payload.value=JSON.stringify(res,null,2);}catch(error){console.log('Failed to Get Control Data',error)}}btnSet.onClick=async()=>{try{awaitwsRequest('POST','/api/control',JSON.parse(payload.value));}catch(error){console.log('Failed to Set Control Data',error);}}btnSubscribe.onClick=async()=>{try{awaitwsRequest('POST','/api/notification/subscribe',{channel:'MyChannel'});}catch(error){console.log('Failed to Set Control Data',error);}}btnUnsubscribe.onClick=async()=>{try{awaitwsRequest('POST','/api/notification/unsubscribe',{channel:'MyChannel'});}catch(error){console.log('Failed to Set Control Data',error);}}