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