123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- #if !BESTHTTP_DISABLE_SOCKETIO
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using BestHTTP.SocketIO;
- using 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;
- // 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
- /// <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
|