I'm using Pusher to implement real time communication.
Here is the function in which I get the data from pusher:
private void PusherOnConnected(object sender)
{
Debug.Log("Connected");
channel.Bind("my-event", (dynamic data) =>
{
Debug.Log("my-event received");
Debug.Log(data.GetType().ToString());
Debug.Log(((JObject)data).ToString()); // <-- last line logged
// See EDIT to see what lines have been added
});
}
When I send an event from pusher like this:
{
"foo": "bar"
}
I'm not able to print from Unity. Here are the logs:
my-event received
Newtonsoft.Json.Linq.JObject
{
"event": "my-event",
"data": "{\r\n \"foo\": \"bar\"\r\n}",
"channel": "my-channel"
}
I'm trying to put it in a C# object, with the JObject.ToObject<>()
method, but it does not work.
- Because one of the key of the JSON has the name
event
, this name cannot be a property of a C# object - I know
event
andchannel
would be astring
type, but what would be the type ofdata
?
How would you transform this dynamic data
variable to an object, knowing that is, apparently, a JObject
?
EDIT
I tried to do what @derHugo suggests, but it still does not want to print the C# property:
PusherEvent.cs
using Newtonsoft.Json;
using System;
[Serializable]
public class PusherEvent
{
[JsonProperty("event")]
public string theEvent;
public string channel;
public Data data;
}
[Serializable]
public class Data
{
public string foo;
}
Inside the method receiving the pusher event (I did not try 1 and 2 simultaneously):
PusherEvent pe = ((JObject)data).ToObject<PusherEvent>(); // 1
PusherEvent pe = JsonConvert.DeserializeObject<PusherEvent>(data); // 2
Debug.Log(pe.channel);
Here are my logs:
As you can see, it will not log the channel property and does not throw any errors...
EDIT 2: complete code
PusherManager.cs
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PusherClient;
using UnityEngine;
public class PusherManager : MonoBehaviour
{
public static PusherManager instance = null;
private Pusher pusher;
private Channel channel;
async Task Start()
{
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
await InitialisePusher();
}
private async Task InitialisePusher()
{
if (pusher == null)
{
pusher = new Pusher("<my-secret-key>", new PusherOptions()
{
Cluster = "eu",
Encrypted = true
});
pusher.Error += OnPusherOnError;
pusher.ConnectionStateChanged += PusherOnConnectionStateChanged;
pusher.Connected += PusherOnConnected;
channel = await pusher.SubscribeAsync("my-channel");
channel.Subscribed += OnChannelOnSubscribed;
await pusher.ConnectAsync();
}
}
private void PusherOnConnected(object sender)
{
Debug.Log("Connected");
channel.Bind("my-event", (dynamic data) =>
{
Debug.Log("my-event received");
Debug.Log(data.GetType().ToString());
Debug.Log(((JObject)data).ToString());
PusherEvent pe = ((JObject)data).ToObject<PusherEvent>();
// PusherEvent pe = JsonConvert.DeserializeObject<PusherEvent>(((JObject)data).ToString());
Debug.Log(pe.channel);
});
}
private void PusherOnConnectionStateChanged(object sender, ConnectionState state)
{
Debug.Log("Connection state changed");
}
private void OnPusherOnError(object s, PusherException e)
{
Debug.Log("Errored");
}
private void OnChannelOnSubscribed(object s)
{
Debug.Log("Subscribed");
}
async Task OnApplicationQuit()
{
if (pusher != null)
{
await pusher.DisconnectAsync();
}
}
}
SOLUTION
I finally managed to do it. The problem was in fact that the root object was a JObject
whereas the data
property of this object was a string
, ~~ and not another JObject
~~:
// PusherManager.cs
// ...
PEvent<FireworkInfo> pe = new PEvent<FireworkInfo>(pusherEvent);
Debug.Log(pe);
// ...
// PEvent.cs
using Newtonsoft.Json.Linq;
using System;
[Serializable]
public class PEvent<T>
{
public string @event;
public string channel;
public T data;
public PEvent(dynamic pusherEvent)
{
this.@event = pusherEvent["event"];
this.channel = pusherEvent["channel"];
this.data = JObject.Parse((string)pusherEvent["data"]).ToObject<T>();
}
public override string ToString()
{
return data.ToString();
}
}