mardi 14 juin 2016

Pubnub SDK translation from Unity to Javascript Function?

In Javascript its basically:

  pubnub.publish({
    channel: 'Chatbox',
    message: {
      username: 'username',
      text: message
    }
  });

  pubnub.subscribe({
    channel: 'Chatbox',
    message: handleMessage
  });

  function handleMessage(message) {
    var messageEl = $("<li class='message'>"
        + "<span class='username'>" + message.username + ": </span>"
        + message.text
        + "</li>");
    messageList.append(messageEl);
    messageList.listview('refresh');

In Unity instead of using message.username. Unity gives a dictionary. Unity seems to be the more complicated one so I would like to translate the unity from string url to publish sdk, if possible.

Here is the UNity Wrapper

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class PubNubWrapper : MonoBehaviour
{

    public static PubNubWrapper instance;
    public string PublishKey = "";
    public string SubscribeKey = "";

    private Dictionary<string, System.Action<string>> channelMessageHandlers = new Dictionary<string, System.Action<string>>();

    private string timeToken = "o";

    void Awake()
    {
        instance = this;
       // Debug.Log("Received message: ");
    }



    //send the ported message
    /// <summary>
    /// The Publish function creates a new JSON string by creating a WWW object. The WWW object is the object
    /// making the requests to the PubNub Server.  Part of the Publish, Subscribe and Unsubscribe requests for web services
    /// </summary>
    /// <param name="message"></param>
    /// <param name="channel"></param>
    public void Publish(string message, string channel)
    {
        //esc the message so we can put it into webservices
        string escapedMessage = WWW.EscapeURL(message).Replace("+", "%20"); // UNity's URL escaping function replaces spaces '+'

        //form the URL
        //http://pubsub/pubnub.com
        // /publish
        // /[publishKey]
        // /[subscribe key]
        // /[o
        // /[channel name]
        // /o
        //  /[JSON message data]

        string url =
               "http://pubsub.pubnub.com" +"/publish" +"/" + PublishKey +"/" + SubscribeKey +"/o" +"/" + channel +"/o" +"/"" + escapedMessage + """;

        //make the request with a newly created WWW object
        WWW www = new WWW(url);
    }
    /// <summary>
    ///  Subscribe creates an open port to listen to published messages sent with a JSON string
    /// </summary>
    /// <param name="channel"> N/a </param>
    /// <param name="messageHandler"> N/a </param>
    public void Subscribe(string channel, System.Action<string> messageHandler)
    {
        channelMessageHandlers.Add(channel, messageHandler);
        StartCoroutine(doSubscribe(channel));

    }

    /// <summary>
    /// The doSubscribe is the action for the channel to listen to for published messages
    /// </summary>
    /// <param name="channel"></param>
    /// <returns></returns>
    IEnumerator doSubscribe(string channel)
    {
        //The mssage handler here will again be JSON for parsing

        while (channelMessageHandlers.ContainsKey(channel))
        {
            //  form the URL
            // /http://pubsub.pubnub.com
            // /subscribe
            // /[subscribe key here]
            // / [channel key here]
            // /o
            // /[time token here]
            string url =
                "http://pubsub.pubnub.com" +
                "/subscribe" +
                "/" + SubscribeKey +
                "/" + channel +
                "/o" +
                "/" + timeToken;

            // make the request
            WWW www = new WWW(url);

            //in Unity we can yield
            // a WWW object whic makes Unity "pause"
            // a subroutine until the request has either encountered and error or done
            yield return www;

            //www.error is a string
            // it will either be null/empty if there is no error, or it 
            // will contain the error message if there was one
            if (!string.IsNullOrEmpty(www.error))
            {
                //log the error to the console
                Debug.LogWarning("Subscribe failed: " + www.error);

                //unsibscribe from the channel automatically

                // yield break causes Unity to stop exiting this
                // coroutine. It is equivalent to a return function

                yield break;
            }

            //parse the JSON response from the client from subscription

            string newToken;
            string[] newMessages = PubNubUtils.ParseSubscribeResponse(
                www.text, out newToken);
            timeToken = newToken;

            //make sure there is a still a subscription

            if (channelMessageHandlers.ContainsKey(channel))
            {
                // handle each message separately
                for (int i = 0; i < newMessages.Length; i++)
                {
                    channelMessageHandlers[channel](newMessages[i]);

                }
            }
        }
    }
    /// <summary>
    /// Listen to the channel for subscriptions
    /// </summary>
    /// <param name="channel"></param>
    public void Unsubscribe(string channel)
    {
        channelMessageHandlers.Remove(channel);
    }
}

Unity GUI components

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Chatbox : MonoBehaviour {

    private string PlayerName;
    private string _playerName;

    private string chatText = "";

    private List<string> messages = new List<string>();
    private Vector2 scrollPosition = Vector2.zero;




    /// <summary>
    /// Initialize all the player preferences with Guestname<0-999> and the name can be changed by /OnGui
    /// </summary>
    void Start()
    {
        PlayerName = PlayerPrefs.GetString("PlayerName", "Guest" + Random.Range(0, 9999));

        _playerName = PlayerName;

        //subscribe to the specific room

        PubNubWrapper.instance.Subscribe("Chatbox", HandleMessage);
    }


    /// <summary>
    /// Handle message sends a string to the list of messages and deletes if over 100
    /// </summary>
    /// <param name="message"></param>
    void HandleMessage(string message)
    {
        Debug.Log(message);
        messages.Add(message);

        if (messages.Count > 100)
            messages.RemoveAt(0);


        //Unity cmlamps the scroll value. Setting it sufficiently high will cause it to scroll to the bottom
        scrollPosition.y = messages.Count * 100f;
    }


    /// <summary>
    /// GUI references for changing the player's name
    /// </summary>
    void OnGUI()
    {
        _playerName = GUILayout.TextField(_playerName, GUILayout.Width(200f));
        if (GUILayout.Button( "Change Name", GUILayout.Width( 200f ) ) )
        {
            //inform other players that the player has changed name
            PubNubWrapper.instance.Publish(PlayerName + " changed their name to " + _playerName, "Chatbox");

            //assign the new name

            PlayerName = _playerName;


        }

        scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(Screen.width), GUILayout.Height(Screen.height - 75f));
        {
            // display each message
            for (int i = 0; i < messages.Count; i++)
            {
                GUILayout.Label(messages[i]);
            }
        }
        GUILayout.EndScrollView();



        GUILayout.BeginHorizontal(GUILayout.Width(Screen.width));
        {


            chatText = GUILayout.TextField(chatText, GUILayout.ExpandWidth(true));
            if(GUILayout.Button( "Send", GUILayout.Width(100f ) ))
            {
                //publish the message the player types as:
                // [playername] : [message]
                if (chatText.StartsWith("/me "))
                {
                    chatText = chatText.Replace("/me", "");
                    PubNubWrapper.instance.Publish(PlayerName + chatText, "Chatbox");

                }
                else
                {
                    PubNubWrapper.instance.Publish(PlayerName + ": " + chatText, "Chatbox");

                }
                // clear the textbox
                chatText = "";
            }

        }
        GUILayout.EndHorizontal();
    }

    /// <summary>
    /// Quit the chat box when the player leaves the room and save it for them later
    /// </summary>
    void OnApplicationQuit()
    {
        PlayerPrefs.SetString("PlayerName", PlayerName);
    }
    // Update is called once per frame
    void Update () {

    }
}

The other thing about this is the webpage will understand the connection, except it won't get the publish and subscribe right. I would like to eventually do more projects so it seems the biggest bottleneck is Unity but I understand I can't do much to change the Asset. '

I do not own the rights to the code, they are taken from the PubNub website and Unity Multiplayer Games textbook. I simply just made the connection of using a runnable server.

Aucun commentaire:

Enregistrer un commentaire