249 lines
7.1 KiB
C#
249 lines
7.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using System.Net;
|
|
using asap.core;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
using Newtonsoft.Json;
|
|
using UniRx;
|
|
using GameCore;
|
|
using game;
|
|
|
|
public interface IRTService
|
|
{
|
|
public void WaitForAPISvrLogin();
|
|
public Task Connect();
|
|
public Task Disconnect();
|
|
public bool IsConnected { get; }
|
|
public IDisposable OnEvent<T>(Action<T> handler);
|
|
public Task<string> Publish(string methodName, string arg1);
|
|
public Task<string> Publish(string methodName, string arg1, string arg2);
|
|
//public void Reset();
|
|
public void Release();
|
|
}
|
|
|
|
public class SignalRService : IRTService
|
|
{
|
|
private HubConnection _hubConnection;
|
|
private ICustomServerMgr _serverMgr;
|
|
private HashSet<Type> _bindedEvent;
|
|
private IEventAggregator _eventAgg;
|
|
private string _url;
|
|
private Dictionary<string, Action<string>> _cachedEvents;
|
|
|
|
public SignalRService(ICustomServerMgr serverMgr, IConfig config)
|
|
{
|
|
this._serverMgr = serverMgr;
|
|
var baseUrl = config.Get<string>(GConstant.K_Event_API_URL, string.Empty);
|
|
#if UNITY_EDITOR
|
|
UnityEngine.Assertions.Assert.IsTrue(!string.IsNullOrEmpty(baseUrl));
|
|
#endif
|
|
_url = baseUrl + "gamehub";
|
|
_eventAgg = new EventAggregator();
|
|
_cachedEvents = new Dictionary<string, Action<string>>();
|
|
_bindedEvent = new HashSet<Type>();
|
|
}
|
|
|
|
public void WaitForAPISvrLogin()
|
|
{
|
|
GContext.OnEvent<game.EvtAPISvrLoginSuccess>().Subscribe(OnApiSvrLoginSuccess);
|
|
}
|
|
|
|
private async void OnApiSvrLoginSuccess(EvtAPISvrLoginSuccess evt)
|
|
{
|
|
try{
|
|
Reset();
|
|
await Connect();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogException(ex);
|
|
}
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
if (_hubConnection != null)
|
|
{
|
|
_hubConnection.StopAsync();
|
|
_hubConnection.DisposeAsync();
|
|
_hubConnection = null;
|
|
}
|
|
|
|
if (_bindedEvent != null)
|
|
{
|
|
_bindedEvent.Clear();
|
|
_bindedEvent = null;
|
|
}
|
|
|
|
if (_eventAgg != null)
|
|
{
|
|
_eventAgg = null;
|
|
}
|
|
|
|
if(_cachedEvents != null)
|
|
{
|
|
_cachedEvents.Clear();
|
|
_cachedEvents = null;
|
|
}
|
|
}
|
|
|
|
|
|
private void Reset()
|
|
{
|
|
if (_hubConnection != null)
|
|
{
|
|
_hubConnection.StopAsync();
|
|
_hubConnection.DisposeAsync();
|
|
_hubConnection = null;
|
|
}
|
|
|
|
var cookie = _serverMgr.Cookie;
|
|
_hubConnection = new HubConnectionBuilder()
|
|
.WithUrl(_url, option => option.Cookies = cookie)
|
|
.WithAutomaticReconnect()
|
|
.Build();
|
|
|
|
_hubConnection.Reconnected += OnHubConnected;
|
|
|
|
_hubConnection.On<string,string, string>("ForceQuit", ForceQuit);
|
|
|
|
if (_bindedEvent != null)
|
|
{
|
|
_bindedEvent.Clear();
|
|
}
|
|
else
|
|
{
|
|
_bindedEvent = new HashSet<Type>();
|
|
}
|
|
}
|
|
|
|
private Task OnHubConnected(string connectionId)
|
|
{
|
|
if(_cachedEvents.Count > 0)
|
|
{
|
|
foreach(var kv in _cachedEvents)
|
|
{
|
|
_hubConnection.On<string>(kv.Key, kv.Value);
|
|
}
|
|
_cachedEvents.Clear();
|
|
}
|
|
_hubConnection.Reconnected -= OnHubConnected;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public bool IsConnected => _hubConnection != null && _hubConnection.State == HubConnectionState.Connected;
|
|
|
|
public async Task Connect()
|
|
{
|
|
if(_hubConnection == null)
|
|
{
|
|
Debug.LogWarning("[RTService] hubConnection is null");
|
|
return;
|
|
}
|
|
|
|
//UnityEngine.Assertions.Assert.IsNotNull(_hubConnection, "[RTService] hubConnection is null");
|
|
if (_hubConnection.State == HubConnectionState.Disconnected)
|
|
{
|
|
await _hubConnection.StartAsync();
|
|
Debug.Log($"[RTService] Connected to SignalR server {_hubConnection.State == HubConnectionState.Connected}");
|
|
}
|
|
}
|
|
|
|
public async Task Disconnect()
|
|
{
|
|
if(_hubConnection == null)
|
|
{
|
|
Debug.LogWarning("[RTService] hubConnection is null");
|
|
return;
|
|
}
|
|
|
|
//UnityEngine.Assertions.Assert.IsNotNull(_hubConnection, "[RTService] hubConnection is null");
|
|
if (_hubConnection.State == HubConnectionState.Connected)
|
|
{
|
|
await _hubConnection.StopAsync();
|
|
Debug.Log($"[RTService] Disconnected to SignalR server {_hubConnection.State == HubConnectionState.Disconnected}");
|
|
}
|
|
}
|
|
|
|
public IDisposable OnEvent<T>(Action<T> handler)
|
|
{
|
|
var methodName = typeof(T).Name;
|
|
|
|
if(!_bindedEvent.Contains(typeof(T)))
|
|
{
|
|
_bindedEvent.Add(typeof(T));
|
|
if(IsConnected)
|
|
{
|
|
_hubConnection.On<string>(methodName, data => {
|
|
var result =JsonConvert.DeserializeObject<T>(data);
|
|
_eventAgg.Publish(result);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
_cachedEvents[methodName] = data => {
|
|
|
|
var result =JsonConvert.DeserializeObject<T>(data);
|
|
_eventAgg.Publish(result);
|
|
};
|
|
}
|
|
}
|
|
|
|
return _eventAgg.GetEvent<T>().Subscribe(handler);
|
|
}
|
|
|
|
public async Task<string> Publish(string methodName, string arg1)
|
|
{
|
|
try
|
|
{
|
|
return await _hubConnection.InvokeAsync<string>(methodName, arg1);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Debug.LogException(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<string> Publish(string methodName, string arg1, string arg2)
|
|
{
|
|
try
|
|
{
|
|
return await _hubConnection.InvokeAsync<string>(methodName, arg1, arg2);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Debug.LogException(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private async void ForceQuit(string titleKey, string infoKey, string btnKey)
|
|
{
|
|
await Awaiters.NextFrame;
|
|
GameObject go = await UIManager.Instance.ShowUI(UITypes.NoticeConfirmPopupPanel);
|
|
var noticeConfirmPopupPanel = go.GetComponent<NoticeConfirmPopupPanel>();
|
|
string title = LocalizationMgr.GetText(titleKey ?? "UI_NoticePopupPanel_3");
|
|
string info = LocalizationMgr.GetText(infoKey ?? "UI_NoticePopupPanel_4");
|
|
string label = LocalizationMgr.GetText(btnKey ?? "UI_COMMON_confirm");
|
|
noticeConfirmPopupPanel.Init(1, title, info, onClickLeft: Restart, onClose: Restart, btn_left_text: label);
|
|
}
|
|
|
|
private async void Restart()
|
|
{
|
|
await LoadingScreen.Show();
|
|
await GContext.container.Resolve<IStageService>().SwitchStageAsync("QuitStage");
|
|
}
|
|
|
|
public async void Test()
|
|
{
|
|
Debug.Log("[RTService] Test invoking");
|
|
var returnValue = await _hubConnection.InvokeAsync<string>("Test","arg1", "arg2");
|
|
Debug.Log($"[RTService] Test invoked Value {returnValue}");
|
|
}
|
|
|
|
}
|