csharp-sdk-upm/RTM/Source/Internal/WebSocket/Portable/DefaultWebSocketClient.Port...

165 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Websockets;
namespace LeanCloud.Realtime.Internal
{
/// <summary>
/// LeanCloud Realtime SDK for .NET Portable 内置默认的 WebSocketClient
/// </summary>
public class DefaultWebSocketClient : IWebSocketClient
{
internal IWebSocketConnection connection;
/// <summary>
/// LeanCluod .NET Realtime SDK 内置默认的 WebSocketClient
/// 开发者可以在初始化的时候指定自定义的 WebSocketClient
/// </summary>
public DefaultWebSocketClient()
{
}
public event Action<int, string, string> OnClosed;
public event Action OnOpened;
public event Action<string> OnMessage;
public bool IsOpen
{
get
{
return connection != null && connection.IsOpen;
}
}
public void Close()
{
if (connection != null)
{
connection.OnOpened -= Connection_OnOpened;
connection.OnMessage -= Connection_OnMessage;
connection.OnClosed -= Connection_OnClosed;
connection.OnError -= Connection_OnError;
try {
connection.Close();
} catch (Exception e) {
AVRealtime.PrintLog(string.Format("close websocket error: {0}", e.Message));
}
}
}
public void Disconnect() {
connection?.Close();
}
public void Open(string url, string protocol = null)
{
// 在每次打开时,重新创建 WebSocket 对象
connection = WebSocketFactory.Create();
connection.OnOpened += Connection_OnOpened;
connection.OnMessage += Connection_OnMessage;
connection.OnClosed += Connection_OnClosed;
connection.OnError += Connection_OnError;
if (!string.IsNullOrEmpty(protocol))
{
url = string.Format("{0}?subprotocol={1}", url, protocol);
}
connection.Open(url, protocol);
}
private void Connection_OnOpened()
{
OnOpened?.Invoke();
}
private void Connection_OnMessage(string obj)
{
AVRealtime.PrintLog("websocket<=" + obj);
OnMessage?.Invoke(obj);
}
private void Connection_OnClosed()
{
AVRealtime.PrintLog("PCL websocket closed without parameters..");
OnClosed?.Invoke(0, "", "");
}
private void Connection_OnError(string obj)
{
AVRealtime.PrintLog($"PCL websocket error: {obj}");
connection?.Close();
}
public void Send(string message)
{
if (connection != null)
{
if (this.IsOpen)
{
connection.Send(message);
}
else
{
var log = "Connection is NOT open when send message";
AVRealtime.PrintLog(log);
connection?.Close();
}
}
else {
AVRealtime.PrintLog("Connection is NULL");
}
}
public Task<bool> Connect(string url, string protocol = null) {
var tcs = new TaskCompletionSource<bool>();
Action onOpen = null;
Action onClose = null;
Action<string> onError = null;
onOpen = () => {
AVRealtime.PrintLog("PCL websocket opened");
connection.OnOpened -= onOpen;
connection.OnClosed -= onClose;
connection.OnError -= onError;
// 注册事件
connection.OnMessage += Connection_OnMessage;
connection.OnClosed += Connection_OnClosed;
connection.OnError += Connection_OnError;
tcs.SetResult(true);
};
onClose = () => {
connection.OnOpened -= onOpen;
connection.OnClosed -= onClose;
connection.OnError -= onError;
tcs.SetException(new Exception("连接关闭"));
};
onError = (err) => {
AVRealtime.PrintLog(string.Format("连接错误:{0}", err));
connection.OnOpened -= onOpen;
connection.OnClosed -= onClose;
connection.OnError -= onError;
try {
connection.Close();
} catch (Exception e) {
AVRealtime.PrintLog(string.Format("关闭错误的 WebSocket 异常:{0}", e.Message));
} finally {
tcs.SetException(new Exception(string.Format("连接错误:{0}", err)));
}
};
// 在每次打开时,重新创建 WebSocket 对象
connection = WebSocketFactory.Create();
connection.OnOpened += onOpen;
connection.OnClosed += onClose;
connection.OnError += onError;
//
if (!string.IsNullOrEmpty(protocol)) {
url = string.Format("{0}?subprotocol={1}", url, protocol);
}
connection.Open(url, protocol);
return tcs.Task;
}
}
}