#if !BESTHTTP_DISABLE_SOCKETIO
using System;
using System.Collections.Generic;
using UnityEngine;
using BestHTTP.SocketIO;
using BestHTTP.Examples;
public sealed class SocketIOWePlaySample : MonoBehaviour
{
///
/// Possible states of the game.
///
enum States
{
Connecting,
WaitForNick,
Joined
}
///
/// Controls that the server understands as a parameter in the move event.
///
private string[] controls = new string[] { "left", "right", "a", "b", "up", "down", "select", "start" };
///
/// Ratio of the drawn GUI texture from the screen
///
private const float ratio = 1.5f;
///
/// How many messages to keep.
///
private int MaxMessages = 50;
///
/// Current state of the game.
///
private States State;
///
/// The root("/") Socket instance.
///
private Socket Socket;
///
/// The user-selected nickname.
///
private string Nick = string.Empty;
///
/// The message that the user want to send to the chat.
///
private string messageToSend = string.Empty;
///
/// How many user connected to the server.
///
private int connections;
///
/// Local and server sent messages.
///
private List messages = new List();
///
/// The chat scroll position.
///
private Vector2 scrollPos;
///
/// The decoded texture from the server sent binary data
///
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;
// SaveLocal 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
///
/// Called from an OnGUI event to draw the Login Screen.
///
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();
}
///
/// Add a message to the message log
///
///
void AddMessage(string msg)
{
messages.Insert(0, msg);
if (messages.Count > MaxMessages)
messages.RemoveRange(MaxMessages, messages.Count - MaxMessages);
}
///
/// Send a chat message. The message must be in the messageToSend field.
///
void SendMessage()
{
if (string.IsNullOrEmpty(messageToSend))
return;
Socket.Emit("message", messageToSend);
AddMessage(string.Format("{0}: {1}", Nick, messageToSend));
messageToSend = string.Empty;
}
///
/// Join to the game with the nickname stored in the Nick field.
///
void Join()
{
PlayerPrefs.SetString("Nick", Nick);
Socket.Emit("join", Nick);
}
///
/// Reload the game.
///
void Reload()
{
FrameTexture = null;
if (Socket != null)
{
Socket.Manager.Close();
Socket = null;
Start();
}
}
#endregion
#region SocketIO Events
///
/// Socket connected event.
///
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");
}
///
/// Local player joined after sending a 'join' event
///
private void OnJoined(Socket socket, Packet packet, params object[] args)
{
State = States.Joined;
}
///
/// Server sent us a 'reload' event.
///
private void OnReload(Socket socket, Packet packet, params object[] args)
{
Reload();
}
///
/// Someone wrote a message to the chat.
///
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]));
}
///
/// Someone (including us) pressed a button.
///
private void OnMove(Socket socket, Packet packet, params object[] args)
{
AddMessage(string.Format("{0} pressed {1}", args[1], args[0]));
}
///
/// Someone joined to the game
///
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));
}
///
/// How many players are connected to the game.
///
private void OnConnections(Socket socket, Packet packet, params object[] args)
{
connections = Convert.ToInt32(args[0]);
}
///
/// The server sent us a new picture to draw the game.
///
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);
}
///
/// Called on local or remote error.
///
private void OnError(Socket socket, Packet packet, params object[] args)
{
AddMessage(string.Format("--ERROR - {0}", args[0].ToString()));
}
#endregion
}
#endif