mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 02:36:14 +00:00
提交Unity 联机Pro
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.Examples.Helpers;
|
||||
using BestHTTP.SocketIO3;
|
||||
using BestHTTP.SocketIO3.Events;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BestHTTP.Examples.SocketIO3
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
class LoginData
|
||||
{
|
||||
[PlatformSupport.IL2CPP.Preserve] public int numUsers;
|
||||
}
|
||||
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
sealed class NewMessageData
|
||||
{
|
||||
[PlatformSupport.IL2CPP.Preserve] public string username;
|
||||
[PlatformSupport.IL2CPP.Preserve] public string message;
|
||||
}
|
||||
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
sealed class UserJoinedData : LoginData
|
||||
{
|
||||
[PlatformSupport.IL2CPP.Preserve] public string username;
|
||||
}
|
||||
|
||||
[PlatformSupport.IL2CPP.Preserve]
|
||||
sealed class TypingData
|
||||
{
|
||||
[PlatformSupport.IL2CPP.Preserve] public string username;
|
||||
}
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
public sealed class ChatSample : BestHTTP.Examples.Helpers.SampleBase
|
||||
{
|
||||
private readonly TimeSpan TYPING_TIMER_LENGTH = TimeSpan.FromMilliseconds(700);
|
||||
|
||||
#pragma warning disable 0649, 0414
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The Socket.IO service address to connect to")]
|
||||
private string address = "https://socket-io-3-chat-5ae3v.ondigitalocean.app";
|
||||
|
||||
[Header("Login Details")]
|
||||
[SerializeField]
|
||||
private RectTransform _loginRoot;
|
||||
|
||||
[SerializeField]
|
||||
private InputField _userNameInput;
|
||||
|
||||
[Header("Chat Setup")]
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform _chatRoot;
|
||||
|
||||
[SerializeField]
|
||||
private Text _participantsText;
|
||||
|
||||
[SerializeField]
|
||||
private ScrollRect _scrollRect;
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform _contentRoot;
|
||||
|
||||
[SerializeField]
|
||||
private TextListItem _listItemPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private int _maxListItemEntries = 100;
|
||||
|
||||
[SerializeField]
|
||||
private Text _typingUsersText;
|
||||
|
||||
[SerializeField]
|
||||
private InputField _input;
|
||||
|
||||
[Header("Buttons")]
|
||||
|
||||
[SerializeField]
|
||||
private Button _connectButton;
|
||||
|
||||
[SerializeField]
|
||||
private Button _closeButton;
|
||||
|
||||
#pragma warning restore
|
||||
|
||||
/// <summary>
|
||||
/// The Socket.IO manager instance.
|
||||
/// </summary>
|
||||
private SocketManager Manager;
|
||||
|
||||
/// <summary>
|
||||
/// True if the user is currently typing
|
||||
/// </summary>
|
||||
private bool typing;
|
||||
|
||||
/// <summary>
|
||||
/// When the message changed.
|
||||
/// </summary>
|
||||
private DateTime lastTypingTime = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Users that typing.
|
||||
/// </summary>
|
||||
private List<string> typingUsers = new List<string>();
|
||||
|
||||
|
||||
#region Unity Events
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
this._userNameInput.text = PlayerPrefs.GetString("SocketIO3ChatSample_UserName");
|
||||
SetButtons(!string.IsNullOrEmpty(this._userNameInput.text), false);
|
||||
SetPanels(true);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (this.Manager != null)
|
||||
{
|
||||
// Leaving this sample, close the socket
|
||||
this.Manager.Close();
|
||||
this.Manager = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnUserNameInputChanged(string userName)
|
||||
{
|
||||
SetButtons(!string.IsNullOrEmpty(userName), false);
|
||||
}
|
||||
|
||||
public void OnUserNameInputSubmit(string userName)
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetKeyDown(KeyCode.Return))
|
||||
OnConnectButton();
|
||||
}
|
||||
|
||||
public void UpdateTyping()
|
||||
{
|
||||
if (!typing)
|
||||
{
|
||||
typing = true;
|
||||
Manager.Socket.Emit("typing");
|
||||
}
|
||||
|
||||
lastTypingTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public void OnMessageInput(string textToSend)
|
||||
{
|
||||
if ((!Input.GetKeyDown(KeyCode.KeypadEnter) && !Input.GetKeyDown(KeyCode.Return)) || string.IsNullOrEmpty(textToSend))
|
||||
return;
|
||||
|
||||
Manager.Socket.Emit("new message", textToSend);
|
||||
|
||||
AddText(string.Format("{0}: {1}", this._userNameInput.text, textToSend));
|
||||
}
|
||||
|
||||
public void OnConnectButton()
|
||||
{
|
||||
SetPanels(false);
|
||||
|
||||
PlayerPrefs.SetString("SocketIO3ChatSample_UserName", this._userNameInput.text);
|
||||
|
||||
AddText("Connecting...");
|
||||
|
||||
// Create the Socket.IO manager
|
||||
Manager = new SocketManager(new Uri(this.address));
|
||||
|
||||
Manager.Socket.On<ConnectResponse>(SocketIOEventTypes.Connect, OnConnected);
|
||||
Manager.Socket.On(SocketIOEventTypes.Disconnect, OnDisconnected);
|
||||
|
||||
Manager.Socket.On<LoginData>("login", OnLogin);
|
||||
Manager.Socket.On<NewMessageData>("new message", OnNewMessage);
|
||||
Manager.Socket.On<UserJoinedData>("user joined", OnUserJoined);
|
||||
Manager.Socket.On<UserJoinedData>("user left", OnUserLeft);
|
||||
Manager.Socket.On<TypingData>("typing", OnTyping);
|
||||
Manager.Socket.On<TypingData>("stop typing", OnStopTyping);
|
||||
|
||||
SetButtons(false, true);
|
||||
}
|
||||
|
||||
public void OnCloseButton()
|
||||
{
|
||||
SetButtons(false, false);
|
||||
this.Manager.Close();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (typing)
|
||||
{
|
||||
var typingTimer = DateTime.UtcNow;
|
||||
var timeDiff = typingTimer - lastTypingTime;
|
||||
if (timeDiff >= TYPING_TIMER_LENGTH)
|
||||
{
|
||||
Manager.Socket.Emit("stop typing");
|
||||
typing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SocketIO Events
|
||||
|
||||
private void OnConnected(ConnectResponse resp)
|
||||
{
|
||||
AddText("Connected! Socket.IO SID: " + resp.sid);
|
||||
|
||||
Manager.Socket.Emit("add user", this._userNameInput.text);
|
||||
this._input.interactable = true;
|
||||
}
|
||||
|
||||
private void OnDisconnected()
|
||||
{
|
||||
AddText("Disconnected!");
|
||||
|
||||
SetPanels(true);
|
||||
SetButtons(true, false);
|
||||
}
|
||||
|
||||
private void OnLogin(LoginData data)
|
||||
{
|
||||
AddText("Welcome to Socket.IO Chat");
|
||||
|
||||
if (data.numUsers == 1)
|
||||
this._participantsText.text = "there's 1 participant";
|
||||
else
|
||||
this._participantsText.text = "there are " + data.numUsers + " participants";
|
||||
}
|
||||
|
||||
private void OnNewMessage(NewMessageData data)
|
||||
{
|
||||
AddText(string.Format("{0}: {1}", data.username, data.message));
|
||||
}
|
||||
|
||||
private void OnUserJoined(UserJoinedData data)
|
||||
{
|
||||
AddText(string.Format("{0} joined", data.username));
|
||||
|
||||
if (data.numUsers == 1)
|
||||
this._participantsText.text = "there's 1 participant";
|
||||
else
|
||||
this._participantsText.text = "there are " + data.numUsers + " participants";
|
||||
}
|
||||
|
||||
private void OnUserLeft(UserJoinedData data)
|
||||
{
|
||||
AddText(string.Format("{0} left", data.username));
|
||||
|
||||
if (data.numUsers == 1)
|
||||
this._participantsText.text = "there's 1 participant";
|
||||
else
|
||||
this._participantsText.text = "there are " + data.numUsers + " participants";
|
||||
}
|
||||
|
||||
private void OnTyping(TypingData data)
|
||||
{
|
||||
int idx = typingUsers.FindIndex((name) => name.Equals(data.username));
|
||||
if (idx == -1)
|
||||
typingUsers.Add(data.username);
|
||||
|
||||
SetTypingUsers();
|
||||
}
|
||||
|
||||
private void OnStopTyping(TypingData data)
|
||||
{
|
||||
int idx = typingUsers.FindIndex((name) => name.Equals(data.username));
|
||||
if (idx != -1)
|
||||
typingUsers.RemoveAt(idx);
|
||||
|
||||
SetTypingUsers();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void AddText(string text)
|
||||
{
|
||||
GUIHelper.AddText(this._listItemPrefab, this._contentRoot, text, this._maxListItemEntries, this._scrollRect);
|
||||
}
|
||||
|
||||
private void SetTypingUsers()
|
||||
{
|
||||
if (this.typingUsers.Count > 0)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder(this.typingUsers[0], this.typingUsers.Count + 1);
|
||||
|
||||
for (int i = 1; i < this.typingUsers.Count; ++i)
|
||||
sb.AppendFormat(", {0}", this.typingUsers[i]);
|
||||
|
||||
if (this.typingUsers.Count == 1)
|
||||
sb.Append(" is typing!");
|
||||
else
|
||||
sb.Append(" are typing!");
|
||||
|
||||
this._typingUsersText.text = sb.ToString();
|
||||
}
|
||||
else
|
||||
this._typingUsersText.text = string.Empty;
|
||||
}
|
||||
|
||||
private void SetPanels(bool login)
|
||||
{
|
||||
if (login)
|
||||
{
|
||||
this._loginRoot.gameObject.SetActive(true);
|
||||
this._chatRoot.gameObject.SetActive(false);
|
||||
this._input.interactable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._loginRoot.gameObject.SetActive(false);
|
||||
this._chatRoot.gameObject.SetActive(true);
|
||||
this._input.interactable = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetButtons(bool connect, bool close)
|
||||
{
|
||||
if (this._connectButton != null)
|
||||
this._connectButton.interactable = connect;
|
||||
|
||||
if (this._closeButton != null)
|
||||
this._closeButton.interactable = close;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0787028fcb595bf43b8639c4ba5a8aea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32c47f799d574ac40b44cc0c2f3d50e4
|
||||
timeCreated: 1571299108
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7f5144e14f958b4f866da79ede3d6f9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,562 @@
|
||||
#if !BESTHTTP_DISABLE_SOCKETIO && BESTHTTP_SOCKETIO_ENABLE_NEWTONSOFT_JSON_DOTNET_ENCODER
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
using BestHTTP.SocketIO3.Events;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BestHTTP.SocketIO3.Parsers
|
||||
{
|
||||
public sealed class JsonDotNetParser : IParser
|
||||
{
|
||||
private IncomingPacket PacketWithAttachment = IncomingPacket.Empty;
|
||||
private JsonSerializerSettings _settings;
|
||||
|
||||
public JsonDotNetParser()
|
||||
{ }
|
||||
|
||||
public JsonDotNetParser(JsonSerializerSettings settings)
|
||||
{
|
||||
this._settings = settings;
|
||||
}
|
||||
|
||||
private int ToInt(char ch)
|
||||
{
|
||||
int charValue = Convert.ToInt32(ch);
|
||||
int num = charValue - '0';
|
||||
if (num < 0 || num > 9)
|
||||
return -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public IncomingPacket Parse(SocketManager manager, string from)
|
||||
{
|
||||
int idx = 0;
|
||||
var transportEvent = (TransportEventTypes)ToInt(from[idx++]);
|
||||
var socketIOEvent = SocketIOEventTypes.Unknown;
|
||||
var nsp = string.Empty;
|
||||
var id = -1;
|
||||
var payload = string.Empty;
|
||||
int attachments = 0;
|
||||
|
||||
if (from.Length > idx && ToInt(from[idx]) >= 0)
|
||||
socketIOEvent = (SocketIOEventTypes)ToInt(from[idx++]);
|
||||
else
|
||||
socketIOEvent = SocketIOEventTypes.Unknown;
|
||||
|
||||
// Parse Attachment
|
||||
if (socketIOEvent == SocketIOEventTypes.BinaryEvent || socketIOEvent == SocketIOEventTypes.BinaryAck)
|
||||
{
|
||||
int endIdx = from.IndexOf('-', idx);
|
||||
if (endIdx == -1)
|
||||
endIdx = from.Length;
|
||||
|
||||
int.TryParse(from.Substring(idx, endIdx - idx), out attachments);
|
||||
|
||||
idx = endIdx + 1;
|
||||
}
|
||||
|
||||
// Parse Namespace
|
||||
if (from.Length > idx && from[idx] == '/')
|
||||
{
|
||||
int endIdx = from.IndexOf(',', idx);
|
||||
if (endIdx == -1)
|
||||
endIdx = from.Length;
|
||||
|
||||
nsp = from.Substring(idx, endIdx - idx);
|
||||
idx = endIdx + 1;
|
||||
}
|
||||
else
|
||||
nsp = "/";
|
||||
|
||||
// Parse Id
|
||||
if (from.Length > idx && ToInt(from[idx]) >= 0)
|
||||
{
|
||||
int startIdx = idx++;
|
||||
while (from.Length > idx && ToInt(from[idx]) >= 0)
|
||||
idx++;
|
||||
|
||||
int.TryParse(from.Substring(startIdx, idx - startIdx), out id);
|
||||
}
|
||||
|
||||
// What left is the payload data
|
||||
if (from.Length > idx)
|
||||
payload = from.Substring(idx);
|
||||
else
|
||||
payload = string.Empty;
|
||||
|
||||
var packet = new IncomingPacket(transportEvent, socketIOEvent, nsp, id);
|
||||
packet.AttachementCount = attachments;
|
||||
|
||||
string eventName = packet.EventName;
|
||||
object[] args = null;
|
||||
|
||||
switch (socketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Unknown:
|
||||
packet.DecodedArg = payload;
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
if (!string.IsNullOrEmpty(payload))
|
||||
(eventName, args) = ReadData(manager, packet, payload);
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect:
|
||||
// No Data
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Error:
|
||||
// String | Object
|
||||
(eventName, args) = ReadData(manager, packet, payload);
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.BinaryAck:
|
||||
// Save payload until all attachments arrive
|
||||
if (packet.AttachementCount > 0)
|
||||
packet.DecodedArg = payload;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Array
|
||||
(eventName, args) = ReadData(manager, packet, payload);
|
||||
// Save payload until all attachments arrive
|
||||
if (packet.AttachementCount > 0)
|
||||
packet.DecodedArg = payload;
|
||||
break;
|
||||
}
|
||||
|
||||
packet.EventName = eventName;
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
packet.DecodedArg = args[0];
|
||||
else
|
||||
packet.DecodedArgs = args;
|
||||
}
|
||||
|
||||
if (packet.AttachementCount > 0)
|
||||
{
|
||||
PacketWithAttachment = packet;
|
||||
return IncomingPacket.Empty;
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
public IncomingPacket MergeAttachements(SocketManager manager, IncomingPacket packet)
|
||||
{
|
||||
string payload = packet.DecodedArg as string;
|
||||
packet.DecodedArg = null;
|
||||
|
||||
string placeholderFormat = "{{\"_placeholder\":true,\"num\":{0}}}";
|
||||
|
||||
for (int i = 0; i < packet.Attachements.Count; ++i)
|
||||
{
|
||||
string placeholder = string.Format(placeholderFormat, i);
|
||||
BufferSegment data = packet.Attachements[i];
|
||||
|
||||
payload = payload.Replace(placeholder, "\"" + Convert.ToBase64String(data.Data, data.Offset, data.Count) + "\"");
|
||||
}
|
||||
|
||||
(string eventName, object[] args) = ReadData(manager, packet, payload);
|
||||
|
||||
packet.EventName = eventName;
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
packet.DecodedArg = args[0];
|
||||
else
|
||||
packet.DecodedArgs = args;
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
private (string, object[]) ReadData(SocketManager manager, IncomingPacket packet, string payload)
|
||||
{
|
||||
Socket socket = manager.GetSocket(packet.Namespace);
|
||||
|
||||
string eventName = packet.EventName;
|
||||
Subscription subscription = socket.GetSubscription(eventName);
|
||||
|
||||
object[] args = null;
|
||||
|
||||
switch (packet.SocketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Unknown:
|
||||
// TODO: Error?
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
using (var strReader = new System.IO.StringReader(payload))
|
||||
using (var txtReader = new JsonTextReader(strReader))
|
||||
args = ReadParameters(socket, subscription, txtReader);
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect:
|
||||
// No Data
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Error:
|
||||
// String | Object
|
||||
switch (payload[0])
|
||||
{
|
||||
case '{':
|
||||
using (var strReader = new System.IO.StringReader(payload))
|
||||
using (var txtReader = new JsonTextReader(strReader))
|
||||
args = ReadParameters(socket, subscription, txtReader);
|
||||
break;
|
||||
|
||||
default:
|
||||
args = new object[] { new Error(payload) };
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Ack:
|
||||
case SocketIOEventTypes.BinaryAck:
|
||||
eventName = IncomingPacket.GenerateAcknowledgementNameFromId(packet.Id);
|
||||
subscription = socket.GetSubscription(eventName);
|
||||
|
||||
args = ReadParameters(socket, subscription, JsonConvert.DeserializeObject<List<object>>(payload, this._settings), 0);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// Array
|
||||
|
||||
List<object> array = JsonConvert.DeserializeObject<List<object>>(payload, this._settings);
|
||||
|
||||
if (array.Count > 0)
|
||||
{
|
||||
eventName = array[0].ToString();
|
||||
subscription = socket.GetSubscription(eventName);
|
||||
}
|
||||
|
||||
if (packet.AttachementCount == 0 || packet.Attachements != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
args = ReadParameters(socket, subscription, array, 1);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HTTPManager.Logger.Exception("DefaultJsonParser", string.Format("ReadParameters with eventName: {0}", eventName), ex);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return (eventName, args);
|
||||
}
|
||||
|
||||
private object[] ReadParameters(Socket socket, Subscription subscription, List<object> array, int startIdx)
|
||||
{
|
||||
object[] args = null;
|
||||
|
||||
if (array.Count > startIdx)
|
||||
{
|
||||
var desc = subscription != null ? subscription.callbacks.FirstOrDefault() : default(CallbackDescriptor);
|
||||
int paramCount = desc.ParamTypes != null ? desc.ParamTypes.Length : 0;
|
||||
|
||||
int arrayIdx = startIdx;
|
||||
if (paramCount > 0)
|
||||
{
|
||||
args = new object[paramCount];
|
||||
|
||||
for (int i = 0; i < desc.ParamTypes.Length; ++i)
|
||||
{
|
||||
Type type = desc.ParamTypes[i];
|
||||
|
||||
if (type == typeof(Socket))
|
||||
args[i] = socket;
|
||||
else if (type == typeof(SocketManager))
|
||||
args[i] = socket.Manager;
|
||||
else if (type == typeof(Placeholder))
|
||||
args[i] = new Placeholder();
|
||||
else
|
||||
args[i] = ConvertTo(desc.ParamTypes[i], array[arrayIdx++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
public object ConvertTo(Type toType, object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
#if NETFX_CORE
|
||||
TypeInfo objType = obj.GetType().GetTypeInfo();
|
||||
#else
|
||||
Type objType = obj.GetType();
|
||||
#endif
|
||||
|
||||
#if NETFX_CORE
|
||||
TypeInfo typeInfo = toType.GetTypeInfo();
|
||||
#endif
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsEnum)
|
||||
#else
|
||||
if (toType.IsEnum)
|
||||
#endif
|
||||
return Enum.Parse(toType, obj.ToString(), true);
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsPrimitive)
|
||||
#else
|
||||
if (toType.IsPrimitive)
|
||||
#endif
|
||||
return Convert.ChangeType(obj, toType);
|
||||
|
||||
if (toType == typeof(string))
|
||||
return obj.ToString();
|
||||
|
||||
#if NETFX_CORE
|
||||
if (typeInfo.IsGenericType && toType.Name == "Nullable`1")
|
||||
return Convert.ChangeType(obj, toType.GenericTypeArguments[0]);
|
||||
#else
|
||||
if (toType.IsGenericType && toType.Name == "Nullable`1")
|
||||
return Convert.ChangeType(obj, toType.GetGenericArguments()[0]);
|
||||
#endif
|
||||
|
||||
#if NETFX_CORE
|
||||
if (objType.Equals(typeInfo))
|
||||
#else
|
||||
if (objType.Equals(toType))
|
||||
#endif
|
||||
return obj;
|
||||
|
||||
if (toType == typeof(byte[]) && objType == typeof(string))
|
||||
return Convert.FromBase64String(obj.ToString());
|
||||
|
||||
return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj, this._settings), toType, this._settings);
|
||||
}
|
||||
|
||||
private object[] ReadParameters(Socket socket, Subscription subscription, JsonTextReader reader)
|
||||
{
|
||||
var desc = subscription != null ? subscription.callbacks.FirstOrDefault() : default(CallbackDescriptor);
|
||||
int paramCount = desc.ParamTypes != null ? desc.ParamTypes.Length : 0;
|
||||
object[] args = null;
|
||||
|
||||
if (paramCount > 0)
|
||||
{
|
||||
args = new object[paramCount];
|
||||
|
||||
for (int i = 0; i < desc.ParamTypes.Length; ++i)
|
||||
{
|
||||
Type type = desc.ParamTypes[i];
|
||||
|
||||
if (type == typeof(Socket))
|
||||
args[i] = socket;
|
||||
else if (type == typeof(SocketManager))
|
||||
args[i] = socket.Manager;
|
||||
else
|
||||
{
|
||||
args[i] = JsonSerializer.CreateDefault(this._settings).Deserialize(reader, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
public IncomingPacket Parse(SocketManager manager, BufferSegment data, TransportEventTypes transportEvent = TransportEventTypes.Unknown)
|
||||
{
|
||||
IncomingPacket packet = IncomingPacket.Empty;
|
||||
|
||||
if (PacketWithAttachment.Attachements == null)
|
||||
PacketWithAttachment.Attachements = new List<BufferSegment>(PacketWithAttachment.AttachementCount);
|
||||
PacketWithAttachment.Attachements.Add(data);
|
||||
|
||||
if (PacketWithAttachment.Attachements.Count == PacketWithAttachment.AttachementCount)
|
||||
{
|
||||
packet = manager.Parser.MergeAttachements(manager, PacketWithAttachment);
|
||||
PacketWithAttachment = IncomingPacket.Empty;
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
public OutgoingPacket CreateOutgoing(TransportEventTypes transportEvent, string payload)
|
||||
{
|
||||
return new OutgoingPacket { Payload = "" + (char)('0' + (byte)transportEvent) + payload };
|
||||
}
|
||||
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
public OutgoingPacket CreateOutgoing(Socket socket, SocketIOEventTypes socketIOEvent, int id, string name, object arg)
|
||||
{
|
||||
return CreateOutgoing(socket, socketIOEvent, id, name, arg != null ? new object[] { arg } : null);
|
||||
}
|
||||
|
||||
private int GetBinaryCount(object[] args)
|
||||
{
|
||||
if (args == null || args.Length == 0)
|
||||
return 0;
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
if (args[i] is byte[])
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
public OutgoingPacket CreateOutgoing(Socket socket, SocketIOEventTypes socketIOEvent, int id, string name, object[] args)
|
||||
{
|
||||
builder.Length = 0;
|
||||
List<byte[]> attachements = null;
|
||||
|
||||
switch (socketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Ack:
|
||||
if (GetBinaryCount(args) > 0)
|
||||
{
|
||||
attachements = CreatePlaceholders(args);
|
||||
socketIOEvent = SocketIOEventTypes.BinaryAck;
|
||||
}
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Event:
|
||||
if (GetBinaryCount(args) > 0)
|
||||
{
|
||||
attachements = CreatePlaceholders(args);
|
||||
socketIOEvent = SocketIOEventTypes.BinaryEvent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
builder.Append(((int)TransportEventTypes.Message).ToString());
|
||||
builder.Append(((int)socketIOEvent).ToString());
|
||||
|
||||
if (socketIOEvent == SocketIOEventTypes.BinaryEvent || socketIOEvent == SocketIOEventTypes.BinaryAck)
|
||||
{
|
||||
builder.Append(attachements.Count.ToString());
|
||||
builder.Append('-');
|
||||
}
|
||||
|
||||
// Add the namespace. If there is any other then the root nsp ("/")
|
||||
// then we have to add a trailing "," if we have more data.
|
||||
bool nspAdded = false;
|
||||
if (socket.Namespace != "/")
|
||||
{
|
||||
builder.Append(socket.Namespace);
|
||||
nspAdded = true;
|
||||
}
|
||||
|
||||
// ack id, if any
|
||||
if (id >= 0)
|
||||
{
|
||||
if (nspAdded)
|
||||
{
|
||||
builder.Append(',');
|
||||
nspAdded = false;
|
||||
}
|
||||
|
||||
builder.Append(id.ToString());
|
||||
}
|
||||
|
||||
// payload
|
||||
switch (socketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
if (nspAdded) builder.Append(',');
|
||||
|
||||
builder.Append(JsonConvert.SerializeObject(args[0], this._settings));
|
||||
}
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect:
|
||||
// No Data
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Error:
|
||||
// String | Object
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
if (nspAdded) builder.Append(',');
|
||||
|
||||
builder.Append(JsonConvert.SerializeObject(args[0], this._settings));
|
||||
}
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Ack:
|
||||
case SocketIOEventTypes.BinaryAck:
|
||||
if (nspAdded) builder.Append(',');
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
builder.Append(JsonConvert.SerializeObject(args, this._settings));
|
||||
}
|
||||
else
|
||||
builder.Append("[]");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (nspAdded) builder.Append(',');
|
||||
|
||||
// Array
|
||||
builder.Append('[');
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
builder.Append('\"');
|
||||
builder.Append(name);
|
||||
builder.Append('\"');
|
||||
}
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
builder.Append(',');
|
||||
|
||||
var argsJson = JsonConvert.SerializeObject(args, this._settings);
|
||||
builder.Append(argsJson, 1, argsJson.Length - 2);
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
break;
|
||||
}
|
||||
|
||||
return new OutgoingPacket { Payload = builder.ToString(), Attachements = attachements };
|
||||
}
|
||||
|
||||
private List<byte[]> CreatePlaceholders(object[] args)
|
||||
{
|
||||
List<byte[]> attachements = null;
|
||||
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
var binary = args[i] as byte[];
|
||||
if (binary != null)
|
||||
{
|
||||
if (attachements == null)
|
||||
attachements = new List<byte[]>();
|
||||
attachements.Add(binary);
|
||||
|
||||
args[i] = new Placeholder { _placeholder = true, num = attachements.Count - 1 };
|
||||
}
|
||||
}
|
||||
|
||||
return attachements;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1b1e9a202e74ba4089e4aa518f64109
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,500 @@
|
||||
#if !BESTHTTP_DISABLE_SOCKETIO && BESTHTTP_SOCKETIO_ENABLE_GAMEDEVWARE_MESSAGEPACK
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using BestHTTP.PlatformSupport.Memory;
|
||||
using BestHTTP.SocketIO3.Events;
|
||||
|
||||
using GameDevWare.Serialization;
|
||||
using GameDevWare.Serialization.MessagePack;
|
||||
using GameDevWare.Serialization.Serializers;
|
||||
|
||||
namespace BestHTTP.SocketIO3.Parsers
|
||||
{
|
||||
public sealed class MsgPackParser : IParser
|
||||
{
|
||||
// Variables to calculate an average buffer size to start with in CreateOutgoing
|
||||
ulong sumLength;
|
||||
uint count;
|
||||
|
||||
/// <summary>
|
||||
/// Custom function instead of char.GetNumericValue, as it throws an error under WebGL using the new 4.x runtime.
|
||||
/// It will return the value of the char if it's a numeric one, otherwise -1.
|
||||
/// </summary>
|
||||
private int ToInt(char ch)
|
||||
{
|
||||
int charValue = Convert.ToInt32(ch);
|
||||
int num = charValue - '0';
|
||||
if (num < 0 || num > 9)
|
||||
return -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public IncomingPacket MergeAttachements(SocketManager manager, IncomingPacket packet) { return packet; }
|
||||
|
||||
public IncomingPacket Parse(SocketManager manager, string from)
|
||||
{
|
||||
int idx = 0;
|
||||
var transportEvent = (TransportEventTypes)ToInt(from[idx++]);
|
||||
var socketIOEvent = SocketIOEventTypes.Unknown;
|
||||
var nsp = string.Empty;
|
||||
var id = -1;
|
||||
var payload = string.Empty;
|
||||
int attachments = 0;
|
||||
|
||||
if (from.Length > idx && ToInt(from[idx]) >= 0)
|
||||
socketIOEvent = (SocketIOEventTypes)ToInt(from[idx++]);
|
||||
else
|
||||
socketIOEvent = SocketIOEventTypes.Unknown;
|
||||
|
||||
// Parse Attachment
|
||||
if (socketIOEvent == SocketIOEventTypes.BinaryEvent || socketIOEvent == SocketIOEventTypes.BinaryAck)
|
||||
{
|
||||
int endIdx = from.IndexOf('-', idx);
|
||||
if (endIdx == -1)
|
||||
endIdx = from.Length;
|
||||
|
||||
int.TryParse(from.Substring(idx, endIdx - idx), out attachments);
|
||||
idx = endIdx + 1;
|
||||
}
|
||||
|
||||
// Parse Namespace
|
||||
if (from.Length > idx && from[idx] == '/')
|
||||
{
|
||||
int endIdx = from.IndexOf(',', idx);
|
||||
if (endIdx == -1)
|
||||
endIdx = from.Length;
|
||||
|
||||
nsp = from.Substring(idx, endIdx - idx);
|
||||
idx = endIdx + 1;
|
||||
}
|
||||
else
|
||||
nsp = "/";
|
||||
|
||||
// Parse Id
|
||||
if (from.Length > idx && ToInt(from[idx]) >= 0)
|
||||
{
|
||||
int startIdx = idx++;
|
||||
while (from.Length > idx && ToInt(from[idx]) >= 0)
|
||||
idx++;
|
||||
|
||||
int.TryParse(from.Substring(startIdx, idx - startIdx), out id);
|
||||
}
|
||||
|
||||
// What left is the payload data
|
||||
if (from.Length > idx)
|
||||
payload = from.Substring(idx);
|
||||
else
|
||||
payload = string.Empty;
|
||||
|
||||
return new IncomingPacket(transportEvent, socketIOEvent, nsp, id) { DecodedArg = payload, AttachementCount = attachments };
|
||||
}
|
||||
|
||||
public IncomingPacket Parse(SocketManager manager, BufferSegment data, TransportEventTypes transportEvent = TransportEventTypes.Unknown)
|
||||
{
|
||||
using (var stream = new System.IO.MemoryStream(data.Data, data.Offset, data.Count))
|
||||
{
|
||||
var buff = BufferPool.Get(MsgPackReader.DEFAULT_BUFFER_SIZE, true);
|
||||
try
|
||||
{
|
||||
var context = new SerializationContext
|
||||
{
|
||||
Options = SerializationOptions.SuppressTypeInformation/*,
|
||||
ExtensionTypeHandler = CustomMessagePackExtensionTypeHandler.Instance*/
|
||||
};
|
||||
IJsonReader reader = new MsgPackReader(stream, context, Endianness.BigEndian, buff);
|
||||
|
||||
reader.ReadObjectBegin();
|
||||
|
||||
int type = -1, id = -1;
|
||||
string nsp = null;
|
||||
|
||||
bool hasData = false, readData = false;
|
||||
|
||||
IncomingPacket packet = IncomingPacket.Empty;
|
||||
|
||||
READ:
|
||||
|
||||
while (reader.Token != JsonToken.EndOfObject)
|
||||
{
|
||||
string key = reader.ReadMember();
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case "type":
|
||||
type = reader.ReadByte();
|
||||
break;
|
||||
|
||||
case "nsp":
|
||||
nsp = reader.ReadString();
|
||||
break;
|
||||
|
||||
case "id":
|
||||
id = reader.ReadInt32();
|
||||
break;
|
||||
|
||||
case "data":
|
||||
if (!hasData)
|
||||
{
|
||||
hasData = true;
|
||||
SkipData(reader, (SocketIOEventTypes)type);
|
||||
}
|
||||
else
|
||||
{
|
||||
readData = true;
|
||||
|
||||
packet = new IncomingPacket(transportEvent != TransportEventTypes.Unknown ? transportEvent : TransportEventTypes.Message, (SocketIOEventTypes)type, nsp, id);
|
||||
(string eventName, object[] args) = ReadData(manager, packet, reader);
|
||||
|
||||
packet.EventName = eventName;
|
||||
if (args != null)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
packet.DecodedArg = args[0];
|
||||
else
|
||||
packet.DecodedArgs = args;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// type, nsp, id and data can come in any order. To read data strongly typed we need to know all the additional fields before processing the data field.
|
||||
// In order to do it, when we first encounter the data field we skip it than we do a reset and an additional turn but reading the data too now.
|
||||
if (hasData && !readData)
|
||||
{
|
||||
reader.Reset();
|
||||
stream.Position = 0;
|
||||
reader.ReadObjectBegin();
|
||||
|
||||
goto READ;
|
||||
}
|
||||
|
||||
reader.ReadObjectEnd();
|
||||
|
||||
return packet.Equals(IncomingPacket.Empty) ? new IncomingPacket(transportEvent != TransportEventTypes.Unknown ? transportEvent : TransportEventTypes.Message, (SocketIOEventTypes)type, nsp, id) : packet;
|
||||
}
|
||||
finally
|
||||
{
|
||||
BufferPool.Release(buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SkipData(IJsonReader reader, SocketIOEventTypes type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SocketIOEventTypes.Unknown:
|
||||
// TODO: Error?
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
SkipObject(reader);
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect:
|
||||
// No Data
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Error:
|
||||
// String | Object
|
||||
switch(reader.Token)
|
||||
{
|
||||
case JsonToken.StringLiteral:
|
||||
reader.ReadString();
|
||||
break;
|
||||
|
||||
case JsonToken.BeginObject:
|
||||
SkipObject(reader);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Array
|
||||
SkipArray(reader, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private object[] ReadParameters(Socket socket, Subscription subscription, IJsonReader reader, bool isInArray)
|
||||
{
|
||||
var desc = subscription != null ? subscription.callbacks.FirstOrDefault() : default(CallbackDescriptor);
|
||||
int paramCount = desc.ParamTypes != null ? desc.ParamTypes.Length : 0;
|
||||
object[] args = null;
|
||||
|
||||
if (paramCount > 0)
|
||||
{
|
||||
args = new object[paramCount];
|
||||
|
||||
for (int i = 0; i < desc.ParamTypes.Length; ++i)
|
||||
{
|
||||
Type type = desc.ParamTypes[i];
|
||||
|
||||
if (type == typeof(Socket))
|
||||
args[i] = socket;
|
||||
else if (type == typeof(SocketManager))
|
||||
args[i] = socket.Manager;
|
||||
else
|
||||
args[i] = reader.ReadValue(desc.ParamTypes[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isInArray)
|
||||
{
|
||||
if (reader.Token != JsonToken.EndOfArray)
|
||||
SkipArray(reader, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SkipObject(reader);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
private (string, object[]) ReadData(SocketManager manager, IncomingPacket packet, IJsonReader reader)
|
||||
{
|
||||
Socket socket = manager.GetSocket(packet.Namespace);
|
||||
|
||||
string eventName = packet.EventName;
|
||||
Subscription subscription = socket.GetSubscription(eventName);
|
||||
|
||||
object[] args = null;
|
||||
|
||||
switch (packet.SocketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Unknown:
|
||||
// TODO: Error?
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
args = ReadParameters(socket, subscription, reader, false);
|
||||
//SkipObject(reader);
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect:
|
||||
// No Data
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Error:
|
||||
// String | Object
|
||||
switch(reader.Token)
|
||||
{
|
||||
case JsonToken.StringLiteral:
|
||||
args = new object[] { new Error(reader.ReadString()) };
|
||||
break;
|
||||
|
||||
case JsonToken.BeginObject:
|
||||
args = ReadParameters(socket, subscription, reader, false);
|
||||
//if (subscription == null && args == null)
|
||||
// SkipObject(reader);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Ack:
|
||||
eventName = IncomingPacket.GenerateAcknowledgementNameFromId(packet.Id);
|
||||
subscription = socket.GetSubscription(eventName);
|
||||
|
||||
reader.ReadArrayBegin();
|
||||
|
||||
args = ReadParameters(socket, subscription, reader, true);
|
||||
|
||||
reader.ReadArrayEnd();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Array
|
||||
reader.ReadArrayBegin();
|
||||
eventName = reader.ReadString();
|
||||
|
||||
subscription = socket.GetSubscription(eventName);
|
||||
|
||||
args = ReadParameters(socket, subscription, reader, true);
|
||||
|
||||
reader.ReadArrayEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
return (eventName, args);
|
||||
}
|
||||
|
||||
private void SkipArray(IJsonReader reader, bool alreadyStarted, bool readFinalArrayToken)
|
||||
{
|
||||
if (!alreadyStarted)
|
||||
reader.ReadArrayBegin();
|
||||
|
||||
int arrayBegins = 1;
|
||||
|
||||
while (arrayBegins > 0)
|
||||
{
|
||||
switch (reader.Token)
|
||||
{
|
||||
case JsonToken.BeginArray: arrayBegins++; break;
|
||||
case JsonToken.EndOfArray: arrayBegins--; break;
|
||||
}
|
||||
|
||||
if (readFinalArrayToken || arrayBegins >= 1)
|
||||
reader.NextToken();
|
||||
}
|
||||
}
|
||||
|
||||
private void SkipObject(IJsonReader reader)
|
||||
{
|
||||
reader.ReadObjectBegin();
|
||||
int objectBegins = 1;
|
||||
|
||||
while (objectBegins > 0)
|
||||
{
|
||||
switch (reader.Token)
|
||||
{
|
||||
case JsonToken.BeginObject: objectBegins++; break;
|
||||
case JsonToken.EndOfObject: objectBegins--; break;
|
||||
}
|
||||
reader.NextToken();
|
||||
}
|
||||
}
|
||||
|
||||
public OutgoingPacket CreateOutgoing(TransportEventTypes transportEvent, string payload)
|
||||
{
|
||||
return new OutgoingPacket { Payload = "" + (char)('0' + (byte)transportEvent) + payload };
|
||||
}
|
||||
|
||||
public OutgoingPacket CreateOutgoing(Socket socket, SocketIOEventTypes socketIOEvent, int id, string name, object arg)
|
||||
{
|
||||
return CreateOutgoing(socket, socketIOEvent, id, name, arg != null ? new object[] { arg } : null);
|
||||
}
|
||||
|
||||
public OutgoingPacket CreateOutgoing(Socket socket, SocketIOEventTypes socketIOEvent, int id, string name, object[] args)
|
||||
{
|
||||
var memBufferTargetLength = count == 0 ? 256 : Math.Max(256, (sumLength / count) / 2);
|
||||
|
||||
var memBuffer = BufferPool.Get((long)memBufferTargetLength, true);
|
||||
var stream = new BestHTTP.Extensions.BufferPoolMemoryStream(memBuffer, 0, memBuffer.Length, true, true, false, true);
|
||||
|
||||
var buffer = BufferPool.Get(MsgPackWriter.DEFAULT_BUFFER_SIZE, true);
|
||||
|
||||
var context = new SerializationContext
|
||||
{
|
||||
Options = SerializationOptions.SuppressTypeInformation,
|
||||
EnumSerializerFactory = (enumType) => new EnumNumberSerializer(enumType)/*,
|
||||
ExtensionTypeHandler = CustomMessagePackExtensionTypeHandler.Instance*/
|
||||
};
|
||||
|
||||
var writer = new MsgPackWriter(stream, context, buffer);
|
||||
|
||||
switch (socketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
if (args != null && args.Length > 0 && args[0] != null)
|
||||
writer.WriteObjectBegin(id >= 0 ? 4 : 3);
|
||||
else
|
||||
writer.WriteObjectBegin(id >= 0 ? 3 : 2);
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect: writer.WriteObjectBegin(id > 0 ? 3 : 2); break;
|
||||
case SocketIOEventTypes.Error: writer.WriteObjectBegin(id > 0 ? 4 : 3); break;
|
||||
default: writer.WriteObjectBegin(id >= 0 ? 4 : 3); break;
|
||||
}
|
||||
|
||||
writer.WriteMember("type");
|
||||
writer.Write((int)socketIOEvent);
|
||||
|
||||
writer.WriteMember("nsp");
|
||||
writer.Write(socket.Namespace);
|
||||
|
||||
if (id >= 0)
|
||||
{
|
||||
writer.WriteMember("id");
|
||||
writer.Write(id);
|
||||
}
|
||||
|
||||
switch (socketIOEvent)
|
||||
{
|
||||
case SocketIOEventTypes.Connect:
|
||||
// No Data | Object
|
||||
if (args != null && args.Length > 0 && args[0] != null)
|
||||
{
|
||||
writer.WriteMember("data");
|
||||
writer.WriteValue(args[0], args[0].GetType());
|
||||
}
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Disconnect:
|
||||
// No Data
|
||||
break;
|
||||
|
||||
case SocketIOEventTypes.Error:
|
||||
writer.WriteMember("data");
|
||||
|
||||
// String | Object
|
||||
if (args != null && args.Length > 0)
|
||||
writer.WriteValue(args[0], args[0].GetType());
|
||||
else
|
||||
{
|
||||
writer.WriteObjectBegin(0);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
writer.WriteMember("data");
|
||||
|
||||
// Array
|
||||
|
||||
int argCount = (args != null ? args.Length : 0);
|
||||
writer.WriteArrayBegin(!string.IsNullOrEmpty(name) ? 1 + argCount : argCount);
|
||||
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
writer.Write(name);
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
foreach (var arg in args)
|
||||
{
|
||||
if (arg != null)
|
||||
writer.WriteValue(arg, arg.GetType());
|
||||
else
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
writer.WriteObjectEnd();
|
||||
|
||||
writer.Flush();
|
||||
|
||||
BufferPool.Release(buffer);
|
||||
|
||||
// get how much bytes got written to the buffer
|
||||
int length = (int)stream.Position;
|
||||
|
||||
buffer = stream.GetBuffer();
|
||||
|
||||
sumLength += (ulong)length;
|
||||
count++;
|
||||
|
||||
if(sumLength >= int.MaxValue)
|
||||
{
|
||||
sumLength /= count;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
return new OutgoingPacket { PayloadData = new BufferSegment(buffer, 0, length) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c140b7f57ea9266438bfa03cd086bacf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user