using ChatApp.Shared.Hubs; using ChatApp.Shared.MessagePackObjects; using ChatApp.Shared.Services; using Grpc.Core; using MagicOnion.Client; using System.IO; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UI; namespace Assets.Scripts { public class ChatComponent : MonoBehaviour, IChatHubReceiver { private Channel channel; private IChatHub streamingClient; private IChatService client; private bool isJoin; private bool isSelfDisConnected; public Text ChatText; public Button JoinOrLeaveButton; public Text JoinOrLeaveButtonText; public Button SendMessageButton; public InputField Input; public InputField ReportInput; public Button SendReportButton; public Button DisconnectButon; public Button ExceptionButton; public Button UnaryExceptionButton; void Start() { this.InitializeClient(); this.InitializeUi(); } async void OnDestroy() { // Clean up Hub and channel await this.streamingClient.DisposeAsync(); await this.channel.ShutdownAsync(); } private void InitializeClient() { // Initialize the Hub this.channel = new Channel("localhost", 12345, ChannelCredentials.Insecure); // for SSL/TLS connection //var serverCred = new SslCredentials(File.ReadAllText(Path.Combine(Application.streamingAssetsPath, "server.crt"))); //this.channel = new Channel("test.example.com", 12345, serverCred); this.streamingClient = StreamingHubClient.Connect(this.channel, this); this.RegisterDisconnectEvent(streamingClient); this.client = MagicOnionClient.Create(this.channel); } private void InitializeUi() { this.isJoin = false; this.SendMessageButton.interactable = false; this.ChatText.text = string.Empty; this.Input.text = string.Empty; this.Input.placeholder.GetComponent().text = "Please enter your name."; this.JoinOrLeaveButtonText.text = "Enter the room"; this.ExceptionButton.interactable = false; } private async void RegisterDisconnectEvent(IChatHub streamingClient) { try { // you can wait disconnected event await streamingClient.WaitForDisconnect(); } finally { // try-to-reconnect? logging event? close? etc... Debug.Log("disconnected server."); if (this.isSelfDisConnected) { // there is no particular meaning await Task.Delay(2000); // reconnect this.ReconnectServer(); } } } public async void DisconnectServer() { this.isSelfDisConnected = true; this.JoinOrLeaveButton.interactable = false; this.SendMessageButton.interactable = false; this.SendReportButton.interactable = false; this.DisconnectButon.interactable = false; this.ExceptionButton.interactable = false; this.UnaryExceptionButton.interactable = false; if (this.isJoin) this.JoinOrLeave(); await this.streamingClient.DisposeAsync(); } private void ReconnectServer() { this.streamingClient = StreamingHubClient.Connect(this.channel, this); this.RegisterDisconnectEvent(streamingClient); Debug.Log("Reconnected server."); this.JoinOrLeaveButton.interactable = true; this.SendMessageButton.interactable = false; this.SendReportButton.interactable = true; this.DisconnectButon.interactable = true; this.ExceptionButton.interactable = true; this.UnaryExceptionButton.interactable = true; this.isSelfDisConnected = false; } #region Client -> Server (Streaming) public async void JoinOrLeave() { if (this.isJoin) { await this.streamingClient.LeaveAsync(); this.InitializeUi(); } else { var request = new JoinRequest { RoomName = "SampleRoom", UserName = this.Input.text }; await this.streamingClient.JoinAsync(request); this.isJoin = true; this.SendMessageButton.interactable = true; this.JoinOrLeaveButtonText.text = "Leave the room"; this.Input.text = string.Empty; this.Input.placeholder.GetComponent().text = "Please enter a comment."; this.ExceptionButton.interactable = true; } } public async void SendMessage() { if (!this.isJoin) return; await this.streamingClient.SendMessageAsync(this.Input.text); this.Input.text = string.Empty; } public async void GenerateException() { // hub if (!this.isJoin) return; await this.streamingClient.GenerateException("client exception(streaminghub)!"); } public void SampleMethod() { throw new System.NotImplementedException(); } #endregion #region Server -> Client (Streaming) public void OnJoin(string name) { this.ChatText.text += $"\n{name} entered the room."; } public void OnLeave(string name) { this.ChatText.text += $"\n{name} left the room."; } public void OnSendMessage(MessageResponse message) { this.ChatText.text += $"\n{message.UserName}:{message.Message}"; } #endregion #region Client -> Server (Unary) public async void SendReport() { await this.client.SendReportAsync(this.ReportInput.text); this.ReportInput.text = string.Empty; } public async void UnaryGenerateException() { // unary await this.client.GenerateException("client exception(unary)!"); } #endregion } }