Я использую оба пакета Photon Pun2 и Photon Chat в своем приложении. Но я не могу найти способ отправлять или получать изображения, аудио или видео через личное сообщение.
Есть ли способ отправлять или получать изображения, аудио и видео с помощью Photon Pun2 или Photon Chat?
Ответы (2)
Да есть... Однако она достаточно ограничена.
Насколько велики вещи, которые вы должны отправить?
Чат
В Photon Chat полезная нагрузка сообщения ограничена чем-то между 400 000 и 500 000 байт. Я не проверял это более подробно, но если размер вашего сообщения достигает определенного предела, вы немедленно отключаетесь без надлежащей обратной связи по причине ^^
Пример
public class MyChatListner : IChatClientListener
{
public event Action<byte[]> OnReceived;
private ChatClient cient;
public void Initialize()
{
client = new ChatClient(this);
client.ChatRegion = ...;
client.Connect(....);
}
// Sicne you already work with the chat you should know but anyway
// This has to be called continuously (who knows in what intervals)
public void Heartbeat()
{
client.Service();
}
public void SendData(string recipient, byte[] data)
{
client.SendPrivateMessage(recipient, data);
}
public void OnPrivateMessage(string sender, object message, string channelName)
{
OnReceived?.Invoke((byte[])message);
}
// also will have to implement the other methods from IChatClientListener ...
}
PUN2
В Pun2 я не знаю, существует ли такой лимит, но он определенно задержит все остальное, пока файл не будет полностью получен. Здесь вы можете напрямую отправлять и получать byte[]
через PhotonNetwork.RaiseEvent
и < a href="https://doc-api.photonengine.com/en/PUN/v2/interface_photonpublic class MyChatListner : IChatClientListener
{
public event Action<byte[]> OnReceived;
private ChatClient cient;
public void Initialize()
{
client = new ChatClient(this);
client.ChatRegion = ...;
client.Connect(....);
}
// Sicne you already work with the chat you should know but anyway
// This has to be called continuously (who knows in what intervals)
public void Heartbeat()
{
client.Service();
}
public void SendData(string recipient, byte[] data)
{
client.SendPrivateMessage(recipient, data);
}
public void OnPrivateMessage(string sender, object message, string channelName)
{
OnReceived?.Invoke((byte[])message);
}
// also will have to implement the other methods from IChatClientListener ...
}
1_realtimepublic class MyChatListner : IChatClientListener
{
public event Action<byte[]> OnReceived;
private ChatClient cient;
public void Initialize()
{
client = new ChatClient(this);
client.ChatRegion = ...;
client.Connect(....);
}
// Sicne you already work with the chat you should know but anyway
// This has to be called continuously (who knows in what intervals)
public void Heartbeat()
{
client.Service();
}
public void SendData(string recipient, byte[] data)
{
client.SendPrivateMessage(recipient, data);
}
public void OnPrivateMessage(string sender, object message, string channelName)
{
OnReceived?.Invoke((byte[])message);
}
// also will have to implement the other methods from IChatClientListener ...
}
1_i_on_event_callback.html#a743a99e7fae311f18ac77ecfb3be8e31" rel="nofollow noreferrer">OnEvent
(через интерфейс IOnEventCallback
)
Пример
// doesn't even have to be monobehaviour necessarily
public class FileTransmitter : IOnEventCallback
{
private const byte eventID = 42;
public event Action<byte[]> OnReceived;
public void Enable()
{
PhotonNetwork.AddCallbackTarget(this);
}
public void Disable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
public void SendData(byte[] data, SendOptions sendoptions, RaiseEventOptions raiseEventOptions = null)
{
PhotonNetwork.RaiseEvent(eventID, data, raiseEventOptions, sendoptions);
}
public void OnEvent(EventData photonEvent)
{
if(photonEvent.Code != eventID) return;
var data = (byte[]) photonEvent.CustomData;
OnReceived?.Invoke(data);
}
}
В качестве альтернативы вы, конечно, также можете использовать RPC
напрямую и использовать, например.
public class FileTransfer : MonoBehaviourPun
{
[PunRPC]
void ChatMessage(string fileName, byte[] content)
{
// e.g.
File.WriteAllBytes(Path.Combine(Application.persistentDataPath, fileName), content);
}
public void SendFile(string fileName, byte[] content, PhotonPlayer targetPlayer)
{
photonView.RPC(nameof(ChatMessage), targetPlayer, fileName, content);
}
}
В любом случае лично я использовал только один единственный byte[]
и закодировал в него всю необходимую информацию. Photon в любом случае сделает это со всеми параметрами, но если вы уже точно знаете, какие данные вы отправляете и как их десериализовать, гораздо эффективнее сделать это самостоятельно, например. в потоке/задаче. Затем на стороне получателя я снова десериализовал их в индивидуальную информацию.
Это возможно и работает нормально (хотя вы должны следить за ограничениями, как сказал @derHugo). Моя реализация использует RPC для отправки массива байтов с помощью Texture2D.EncodeToPNG, а затем декодирование его на клиентах при получении.
Чтобы преобразовать массив байтов обратно в изображение, вы можете использовать Texture2D.LoadImage. метод.
Подход аналогичен отправке других типов мультимедиа, отличаются только методы кодирования/декодирования.