#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; // 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 /// /// 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