Connectivity - Code
Indicates status of network connection availability [SOCL-Connectivity-02]
Examples
Here are examples which cover common programming needs.
Beamable SDK Examples
• The following example code is available for download at GitHub.com/Beamable_SDK_Examples
In this ConnectivityServiceExample.cs
, the UI shows the current state of the internet connectivity and updates automatically if any changes occur (ex. if the ethernet / Wi-Fi is manually disabled or enabled by the user).
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Beamable.Examples.Services.ConnectivityService
{
/// <summary>
/// Holds data for use in the <see cref="ConnectivityServiceExampleUI"/>.
/// </summary>
[System.Serializable]
public class ConnectivityServiceExampleData
{
public List<string> OutputLogs = new List<string>();
public bool HasConnectivity = false;
}
[System.Serializable]
public class RefreshedUnityEvent : UnityEvent<ConnectivityServiceExampleData> { }
/// <summary>
/// Demonstrates <see cref="ConnectivityService"/>.
/// </summary>
public class ConnectivityServiceExample : MonoBehaviour
{
// Events ---------------------------------------
[HideInInspector]
public RefreshedUnityEvent OnRefreshed = new RefreshedUnityEvent();
// Fields ---------------------------------------
private BeamContext _beamContext;
private ConnectivityServiceExampleData _data = new ConnectivityServiceExampleData();
// Unity Methods --------------------------------
protected void Start()
{
Debug.Log($"Start() Instructions...\n\n" +
" * Ensure Computer's Internet Is Active\n" +
" * Run The Scene\n" +
" * See Onscreen UI Show HasConnectivity = true\n" +
" * Ensure Computer's Internet Is NOT Active (e.g. Turn off wifi/ethernet)\n" +
" * See Onscreen UI Show HasConnectivity = false\n");
SetupBeamable();
}
// Methods --------------------------------------
private async void SetupBeamable()
{
_beamContext = BeamContext.Default;
await _beamContext.OnReady;
Debug.Log($"beamContext.PlayerId = {_beamContext.PlayerId}");
// Observe ConnectivityService Changes
_beamContext.Api.ConnectivityService.OnConnectivityChanged += ConnectivityService_OnConnectivityChanged;
// Update UI Immediately
bool hasConnectivity = _beamContext.Api.ConnectivityService.HasConnectivity;
ConnectivityService_OnConnectivityChanged(hasConnectivity);
}
public void ToggleHasInternet()
{
_beamContext.Api.ConnectivityService.SetHasInternet(!_data.HasConnectivity);
}
public void Refresh()
{
string refreshLog = $"Refresh() ..." +
$"\n * HasConnectivity = {_data.HasConnectivity}" +
$"\n * OutputLogs = {_data.OutputLogs.Count}\n\n";
//Debug.Log(refreshLog);
// Send relevant data to the UI for rendering
OnRefreshed?.Invoke(_data);
}
// Event Handlers -------------------------------
private void ConnectivityService_OnConnectivityChanged(bool hasConnectivity)
{
_data.HasConnectivity = hasConnectivity;
_data.OutputLogs.Add($"HasConnectivity = {_data.HasConnectivity}");
Refresh();
}
}
}
Disable Network Connection
Game makers can set a global disable to simulate not having wifi before BeamContext initialization.
private static void ForceDisableConnectivity()
{
// to simulate network outage even if the device is online
IConnectivityServiceExtensions.GlobalForceDisabled = true;
}
private async void SetupBeamable()
{
ForceDisableConnectivity();
_beamContext = BeamContext.Default;
await _beamContext.OnReady;
Debug.Log($"beamContext.PlayerId = {_beamContext.PlayerId}");
// Observe ConnectivityService Changes
_beamContext.Api.ConnectivityService.OnConnectivityChanged += ConnectivityService_OnConnectivityChanged;
// Update UI Immediately
bool hasConnectivity = _beamContext.Api.ConnectivityService.HasConnectivity;
ConnectivityService_OnConnectivityChanged(hasConnectivity);
}
Custom Connectivity Service
From version 1.11 and above, you can override the IConnectivityChecker
service via Dependency Injection and change how the connectivity logic works. The default implementation uses a polling approach and sends requests to Beamable's API Gateway.
In the code sample below, there is a custom implementation of IConnectivityService
that pings a local server at "http://127.0.0.1:3000/ping"
.
using System;
using System.Collections;
using Beamable.Api.Connectivity;
using Beamable.Common;
using UnityEngine;
using UnityEngine.Networking;
public class CustomConnectivityService : IConnectivityService
{
private bool _isConnected = true;
public float PollingInterval => 5f;
public bool HasConnectivity => _isConnected && !Disabled;
public bool ForceDisabled { get; set; }
public bool Disabled => ForceDisabled || IConnectivityServiceExtensions.GlobalForceDisabled;
public event Action<bool> OnConnectivityChanged;
public Promise SetHasInternet(bool hasInternet)
{
var promise = new Promise();
if (!Disabled)
{
_isConnected = hasInternet;
OnConnectivityChanged?.Invoke(hasInternet);
}
promise.CompleteSuccess();
return promise;
}
public Promise ReportInternetLoss()
{
Debug.LogError("Internet connection lost");
return SetHasInternet(false);
}
public void OnReconnectOnce(Action onReconnection)
{
if (HasConnectivity) onReconnection.Invoke();
}
public void OnReconnectOnce(ConnectionCallback promise, int order = 0)
{
if (HasConnectivity) _ = promise();
}
// For testing locally, go to Edit > Project Settings > Player > Other Settings
// Then set Allow downloads over HTTP = Allowed in development builds
public IEnumerator PingServer()
{
const string url = "http://127.0.0.1:3000/ping";
using var webRequest = UnityWebRequest.Get(url);
// Send the request asynchronously
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.Success)
{
// Request was successful, and you can handle the response data here.
var responseText = webRequest.downloadHandler.text;
Debug.Log("Response: " + responseText);
// raise connectivity event status to true
OnConnectivityChanged?.Invoke(!Disabled);
}
else
{
// Request failed; handle the error.
Debug.LogError("Request failed: " + webRequest.error);
// raise connectivity event status to false
if (!Disabled) OnConnectivityChanged?.Invoke(false);
}
}
}
This code demonstrated how to override the existing IConnectivityService
[BeamContextSystem]
public class Registrations
{
[RegisterBeamableDependencies]
public static void Build(IDependencyBuilder builder)
{
builder.RemoveIfExists<IConnectivityChecker>();
builder.AddSingleton<IConnectivityChecker, CustomConnectivityService>();
}
}
Load this code into a scene to see the custom implementation in action.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Beamable;
using Beamable.Api.Connectivity; // add this to docs
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// Holds data for use in the <see cref="ConnectivityServiceUI"/>.
/// </summary>
[Serializable]
public class ConnectivityServiceData
{
public List<string> OutputLogs = new List<string>();
public bool HasConnectivity = false;
}
[Serializable]
public class RefreshedUnityEvent : UnityEvent<ConnectivityServiceData> { }
/// <summary>
/// Demonstrates <see cref="CustomConnectivityService"/>.
/// </summary>
public class CustomConnectivityServiceExample : MonoBehaviour
{
// Events ---------------------------------------
[HideInInspector]
public RefreshedUnityEvent OnRefreshed = new();
// Fields ---------------------------------------
private BeamContext _beamContext;
private ConnectivityServiceData _data = new();
private IConnectivityService _connectivityService;
// Properties -----------------------------------
public ConnectivityServiceData Data => _data;
// Unity Methods --------------------------------
protected async void Start()
{
Debug.Log($"Start() Instructions...\n\n" +
" * Ensure Computer's Internet Is Active\n" +
" * Run The Scene\n" +
" * See Onscreen UI Show HasConnectivity = true\n" +
" * Ensure Computer's Internet Is NOT Active (e.g. Turn off wifi/ethernet)\n" +
" * See Onscreen UI Show HasConnectivity = false\n");
SetupConnectivityService(new CustomConnectivityService());
await SetupBeamable();
StartCoroutine(PingCustomServerPolling());
}
private IEnumerator PingCustomServerPolling()
{
if (_connectivityService is not CustomConnectivityService service) yield break;
while (true)
{
StartCoroutine(service.PingServer());
yield return new WaitForSeconds(service.PollingInterval);
}
}
// Methods --------------------------------------
private void SetupConnectivityService(IConnectivityService connectivityService) =>
_connectivityService = connectivityService;
private async Task SetupBeamable()
{
_beamContext = BeamContext.Default;
await _beamContext.OnReady;
Debug.Log($"beamContext.PlayerId = {_beamContext.PlayerId}");
// Observe ConnectivityService Changes
_connectivityService.OnConnectivityChanged += ConnectivityService_OnConnectivityChanged;
}
public void ToggleHasInternet()
{
_connectivityService.SetHasInternet(!_data.HasConnectivity);
}
public void Refresh()
{
string refreshLog = $"Refresh() ..." +
$"\n * HasConnectivity = {_data.HasConnectivity}" +
$"\n * OutputLogs = {_data.OutputLogs.Count}\n\n";
Debug.Log(refreshLog);
// Send relevant data to the UI for rendering
OnRefreshed?.Invoke(_data);
}
// Event Handlers -------------------------------
private void ConnectivityService_OnConnectivityChanged(bool hasConnectivity)
{
_data.HasConnectivity = hasConnectivity;
_data.OutputLogs.Add($"HasConnectivity = {_data.HasConnectivity}");
Refresh();
}
}
Updated about 1 year ago