提交帧同步案例

This commit is contained in:
PC-20230316NUNE\Administrator
2024-01-26 19:15:07 +08:00
parent 3a345ab966
commit 68c4d5e811
3928 changed files with 463020 additions and 1 deletions

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 745fcd55afb34e4429897e798738aebd
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@
#if !BESTHTTP_DISABLE_SOCKETIO
using System;
using System.Collections.Generic;
namespace BestHTTP.SocketIO.JsonEncoders
{
/*using Newtonsoft.Json;
/// <summary>
/// This class uses Newtonsoft's Json encoder (JSON .NET For Unity - http://u3d.as/5q2).
/// </summary>
public sealed class JsonDotNetEncoder : IJsonEncoder
{
public List<object> Decode(string json)
{
return JsonConvert.DeserializeObject<List<object>>(json);
}
public string Encode(List<object> obj)
{
return JsonConvert.SerializeObject(obj);
}
}*/
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c2d9c71662df0b641980b51cd68443fa
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
#if !BESTHTTP_DISABLE_SOCKETIO
using System.Collections.Generic;
using LitJson;
namespace BestHTTP.SocketIO.JsonEncoders
{
/// <summary>
/// This IJsonEncoder implementation uses the LitJson library located in the Examples\LitJson directory.
/// </summary>
public sealed class LitJsonEncoder : IJsonEncoder
{
public List<object> Decode(string json)
{
JsonReader reader = new JsonReader(json);
return JsonMapper.ToObject<List<object>>(reader);
}
public string Encode(List<object> obj)
{
JsonWriter writer = new JsonWriter();
JsonMapper.ToJson(obj, writer);
return writer.ToString();
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0329bd6a6be04394b9da7576fc41d1dc
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,321 @@
#if !BESTHTTP_DISABLE_SOCKETIO
using System;
using System.Collections.Generic;
using UnityEngine;
using BestHTTP.SocketIO;
namespace BestHTTP.Examples
{
public sealed class SocketIOChatSample : MonoBehaviour
{
private readonly TimeSpan TYPING_TIMER_LENGTH = TimeSpan.FromMilliseconds(700);
private enum ChatStates
{
Login,
Chat
}
#region Fields
/// <summary>
/// The Socket.IO manager instance.
/// </summary>
private SocketManager Manager;
/// <summary>
/// Current state of the chat demo.
/// </summary>
private ChatStates State;
/// <summary>
/// The selected nickname
/// </summary>
private string userName = string.Empty;
/// <summary>
/// Currently typing message
/// </summary>
private string message = string.Empty;
/// <summary>
/// Sent and received messages.
/// </summary>
private string chatLog = string.Empty;
/// <summary>
/// Position of the scroller
/// </summary>
private Vector2 scrollPos;
/// <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>();
#endregion
#region Unity Events
void Start()
{
// The current state is Login
State = ChatStates.Login;
// Change an option to show how it should be done
SocketOptions options = new SocketOptions();
options.AutoConnect = false;
options.ConnectWith = BestHTTP.SocketIO.Transports.TransportTypes.WebSocket;
// Create the Socket.IO manager
Manager = new SocketManager(new Uri("https://socket-io-chat.now.sh/socket.io/"), options);
// Set up custom chat events
Manager.Socket.On("login", OnLogin);
Manager.Socket.On("new message", OnNewMessage);
Manager.Socket.On("user joined", OnUserJoined);
Manager.Socket.On("user left", OnUserLeft);
Manager.Socket.On("typing", OnTyping);
Manager.Socket.On("stop typing", OnStopTyping);
// The argument will be an Error object.
Manager.Socket.On(SocketIOEventTypes.Error, (socket, packet, args) => Debug.LogError(string.Format("Error: {0}", args[0].ToString())));
// We set SocketOptions' AutoConnect to false, so we have to call it manually.
Manager.Open();
}
void OnDestroy()
{
// Leaving this sample, close the socket
Manager.Close();
}
void Update()
{
// Go back to the demo selector
if (Input.GetKeyDown(KeyCode.Escape))
SampleSelector.SelectedSample.DestroyUnityObject();
// Stop typing if some time passed without typing
if (typing)
{
var typingTimer = DateTime.UtcNow;
var timeDiff = typingTimer - lastTypingTime;
if (timeDiff >= TYPING_TIMER_LENGTH)
{
Manager.Socket.Emit("stop typing");
typing = false;
}
}
}
void OnGUI()
{
switch (State)
{
case ChatStates.Login: DrawLoginScreen(); break;
case ChatStates.Chat: DrawChatScreen(); break;
}
}
#endregion
#region Chat Logic
/// <summary>
/// Called from an OnGUI event to draw the Login Screen.
/// </summary>
void DrawLoginScreen()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
GUIHelper.DrawCenteredText("What's your nickname?");
userName = GUILayout.TextField(userName);
if (GUILayout.Button("Join"))
SetUserName();
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
});
}
/// <summary>
/// Called from an OnGUI event to draw the Chat Screen.
/// </summary>
void DrawChatScreen()
{
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
GUILayout.BeginVertical();
scrollPos = GUILayout.BeginScrollView(scrollPos);
GUILayout.Label(chatLog, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
GUILayout.EndScrollView();
string typing = string.Empty;
if (typingUsers.Count > 0)
{
typing += string.Format("{0}", typingUsers[0]);
for (int i = 1; i < typingUsers.Count; ++i)
typing += string.Format(", {0}", typingUsers[i]);
if (typingUsers.Count == 1)
typing += " is typing!";
else
typing += " are typing!";
}
GUILayout.Label(typing);
GUILayout.Label("Type here:");
GUILayout.BeginHorizontal();
message = GUILayout.TextField(message);
if (GUILayout.Button("Send", GUILayout.MaxWidth(100)))
SendMessage();
GUILayout.EndHorizontal();
if (GUI.changed)
UpdateTyping();
GUILayout.EndVertical();
});
}
void SetUserName()
{
if (string.IsNullOrEmpty(userName))
return;
State = ChatStates.Chat;
Manager.Socket.Emit("add user", userName);
}
void SendMessage()
{
if (string.IsNullOrEmpty(message))
return;
Manager.Socket.Emit("new message", message);
chatLog += string.Format("{0}: {1}\n", userName, message);
message = string.Empty;
}
void UpdateTyping()
{
if (!typing)
{
typing = true;
Manager.Socket.Emit("typing");
}
lastTypingTime = DateTime.UtcNow;
}
void addParticipantsMessage(Dictionary<string, object> data)
{
int numUsers = Convert.ToInt32(data["numUsers"]);
if (numUsers == 1)
chatLog += "there's 1 participant\n";
else
chatLog += "there are " + numUsers + " participants\n";
}
void addChatMessage(Dictionary<string, object> data)
{
var username = data["username"] as string;
var msg = data["message"] as string;
chatLog += string.Format("{0}: {1}\n", username, msg);
}
void AddChatTyping(Dictionary<string, object> data)
{
var username = data["username"] as string;
typingUsers.Add(username);
}
void RemoveChatTyping(Dictionary<string, object> data)
{
var username = data["username"] as string;
int idx = typingUsers.FindIndex((name) => name.Equals(username));
if (idx != -1)
typingUsers.RemoveAt(idx);
}
#endregion
#region Custom SocketIO Events
void OnLogin(Socket socket, Packet packet, params object[] args)
{
chatLog = "Welcome to Socket.IO Chat — \n";
addParticipantsMessage(args[0] as Dictionary<string, object>);
}
void OnNewMessage(Socket socket, Packet packet, params object[] args)
{
addChatMessage(args[0] as Dictionary<string, object>);
}
void OnUserJoined(Socket socket, Packet packet, params object[] args)
{
var data = args[0] as Dictionary<string, object>;
var username = data["username"] as string;
chatLog += string.Format("{0} joined\n", username);
addParticipantsMessage(data);
}
void OnUserLeft(Socket socket, Packet packet, params object[] args)
{
var data = args[0] as Dictionary<string, object>;
var username = data["username"] as string;
chatLog += string.Format("{0} left\n", username);
addParticipantsMessage(data);
}
void OnTyping(Socket socket, Packet packet, params object[] args)
{
AddChatTyping(args[0] as Dictionary<string, object>);
}
void OnStopTyping(Socket socket, Packet packet, params object[] args)
{
RemoveChatTyping(args[0] as Dictionary<string, object>);
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: feaffc82c9b6aa54ba0e8bf6572d279e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,394 @@
#if !BESTHTTP_DISABLE_SOCKETIO
using System;
using System.Collections.Generic;
using UnityEngine;
using BestHTTP.SocketIO;
namespace BestHTTP.Examples
{
public sealed class SocketIOWePlaySample : MonoBehaviour
{
/// <summary>
/// Possible states of the game.
/// </summary>
enum States
{
Connecting,
WaitForNick,
Joined
}
/// <summary>
/// Controls that the server understands as a parameter in the move event.
/// </summary>
private string[] controls = new string[] { "left", "right", "a", "b", "up", "down", "select", "start" };
/// <summary>
/// Ratio of the drawn GUI texture from the screen
/// </summary>
private const float ratio = 1.5f;
/// <summary>
/// How many messages to keep.
/// </summary>
private int MaxMessages = 50;
/// <summary>
/// Current state of the game.
/// </summary>
private States State;
/// <summary>
/// The root("/") Socket instance.
/// </summary>
private Socket Socket;
/// <summary>
/// The user-selected nickname.
/// </summary>
private string Nick = string.Empty;
/// <summary>
/// The message that the user want to send to the chat.
/// </summary>
private string messageToSend = string.Empty;
/// <summary>
/// How many user connected to the server.
/// </summary>
private int connections;
/// <summary>
/// Local and server sent messages.
/// </summary>
private List<string> messages = new List<string>();
/// <summary>
/// The chat scroll position.
/// </summary>
private Vector2 scrollPos;
/// <summary>
/// The decoded texture from the server sent binary data
/// </summary>
private Texture2D FrameTexture;
#region Unity Events
void Start()
{
// Change an option to show how it should be done
SocketOptions options = new SocketOptions();
options.AutoConnect = false;
// Create the SocketManager instance
var manager = new SocketManager(new Uri("http://io.weplay.io/socket.io/"), options);
// Keep a reference to the root namespace
Socket = manager.Socket;
// Set up our event handlers.
Socket.On(SocketIOEventTypes.Connect, OnConnected);
Socket.On("joined", OnJoined);
Socket.On("connections", OnConnections);
Socket.On("join", OnJoin);
Socket.On("move", OnMove);
Socket.On("message", OnMessage);
Socket.On("reload", OnReload);
// Don't waste cpu cycles on decoding the payload, we are expecting only binary data with this event,
// and we can access it through the packet's Attachments property.
Socket.On("frame", OnFrame, /*autoDecodePayload:*/ false);
// Add error handler, so we can display it
Socket.On(SocketIOEventTypes.Error, OnError);
// We set SocketOptions' AutoConnect to false, so we have to call it manually.
manager.Open();
// We are connecting to the server.
State = States.Connecting;
}
void OnDestroy()
{
// Leaving this sample, close the socket
Socket.Manager.Close();
}
void Update()
{
// Go back to the demo selector
if (Input.GetKeyDown(KeyCode.Escape))
SampleSelector.SelectedSample.DestroyUnityObject();
}
void OnGUI()
{
switch (State)
{
case States.Connecting:
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
GUIHelper.DrawCenteredText("Connecting to the server...");
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
});
break;
case States.WaitForNick:
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
DrawLoginScreen();
});
break;
case States.Joined:
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
{
// Draw Texture
if (FrameTexture != null)
GUILayout.Box(FrameTexture);
DrawControls();
DrawChat();
});
break;
}
}
#endregion
#region Helper Functions
/// <summary>
/// Called from an OnGUI event to draw the Login Screen.
/// </summary>
void DrawLoginScreen()
{
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
GUIHelper.DrawCenteredText("What's your nickname?");
Nick = GUILayout.TextField(Nick);
if (GUILayout.Button("Join"))
Join();
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
}
void DrawControls()
{
GUILayout.BeginHorizontal();
GUILayout.Label("Controls:");
for (int i = 0; i < controls.Length; ++i)
if (GUILayout.Button(controls[i]))
Socket.Emit("move", controls[i]);
GUILayout.Label(" Connections: " + connections);
GUILayout.EndHorizontal();
}
void DrawChat(bool withInput = true)
{
GUILayout.BeginVertical();
// Draw the messages
scrollPos = GUILayout.BeginScrollView(scrollPos, false, false);
for (int i = 0; i < messages.Count; ++i)
GUILayout.Label(messages[i], GUILayout.MinWidth(Screen.width));
GUILayout.EndScrollView();
if (withInput)
{
GUILayout.Label("Your message: ");
GUILayout.BeginHorizontal();
messageToSend = GUILayout.TextField(messageToSend);
if (GUILayout.Button("Send", GUILayout.MaxWidth(100)))
SendMessage();
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
}
/// <summary>
/// Add a message to the message log
/// </summary>
/// <param name="msg"></param>
void AddMessage(string msg)
{
messages.Insert(0, msg);
if (messages.Count > MaxMessages)
messages.RemoveRange(MaxMessages, messages.Count - MaxMessages);
}
/// <summary>
/// Send a chat message. The message must be in the messageToSend field.
/// </summary>
void SendMessage()
{
if (string.IsNullOrEmpty(messageToSend))
return;
Socket.Emit("message", messageToSend);
AddMessage(string.Format("{0}: {1}", Nick, messageToSend));
messageToSend = string.Empty;
}
/// <summary>
/// Join to the game with the nickname stored in the Nick field.
/// </summary>
void Join()
{
PlayerPrefs.SetString("Nick", Nick);
Socket.Emit("join", Nick);
}
/// <summary>
/// Reload the game.
/// </summary>
void Reload()
{
FrameTexture = null;
if (Socket != null)
{
Socket.Manager.Close();
Socket = null;
Start();
}
}
#endregion
#region SocketIO Events
/// <summary>
/// Socket connected event.
/// </summary>
private void OnConnected(Socket socket, Packet packet, params object[] args)
{
if (PlayerPrefs.HasKey("Nick"))
{
Nick = PlayerPrefs.GetString("Nick", "NickName");
Join();
}
else
State = States.WaitForNick;
AddMessage("connected");
}
/// <summary>
/// Local player joined after sending a 'join' event
/// </summary>
private void OnJoined(Socket socket, Packet packet, params object[] args)
{
State = States.Joined;
}
/// <summary>
/// Server sent us a 'reload' event.
/// </summary>
private void OnReload(Socket socket, Packet packet, params object[] args)
{
Reload();
}
/// <summary>
/// Someone wrote a message to the chat.
/// </summary>
private void OnMessage(Socket socket, Packet packet, params object[] args)
{
if (args.Length == 1)
AddMessage(args[0] as string);
else
AddMessage(string.Format("{0}: {1}", args[1], args[0]));
}
/// <summary>
/// Someone (including us) pressed a button.
/// </summary>
private void OnMove(Socket socket, Packet packet, params object[] args)
{
AddMessage(string.Format("{0} pressed {1}", args[1], args[0]));
}
/// <summary>
/// Someone joined to the game
/// </summary>
private void OnJoin(Socket socket, Packet packet, params object[] args)
{
string loc = args.Length > 1 ? string.Format("({0})", args[1]) : string.Empty;
AddMessage(string.Format("{0} joined {1}", args[0], loc));
}
/// <summary>
/// How many players are connected to the game.
/// </summary>
private void OnConnections(Socket socket, Packet packet, params object[] args)
{
connections = Convert.ToInt32(args[0]);
}
/// <summary>
/// The server sent us a new picture to draw the game.
/// </summary>
private void OnFrame(Socket socket, Packet packet, params object[] args)
{
if (State != States.Joined)
return;
if (FrameTexture == null)
{
FrameTexture = new Texture2D(0, 0, TextureFormat.RGBA32, false);
FrameTexture.filterMode = FilterMode.Point;
}
// Binary data usage case 1 - using directly the Attachments property:
byte[] data = packet.Attachments[0];
// Binary data usage case 2 - using the packet's ReconstructAttachmentAsIndex() function
/*packet.ReconstructAttachmentAsIndex();
args = packet.Decode(socket.Manager.Encoder);
data = packet.Attachments[Convert.ToInt32(args[0])];*/
// Binary data usage case 3 - using the packet's ReconstructAttachmentAsBase64() function
/*packet.ReconstructAttachmentAsBase64();
args = packet.Decode(socket.Manager.Encoder);
data = Convert.FromBase64String(args[0] as string);*/
// Load the server sent picture
FrameTexture.LoadImage(data);
}
/// <summary>
/// Called on local or remote error.
/// </summary>
private void OnError(Socket socket, Packet packet, params object[] args)
{
AddMessage(string.Format("--ERROR - {0}", args[0].ToString()));
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3ce53a6e4419d8f429db4a753d71a0c2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: