Есть ли способ отправлять или получать изображения, аудио и видео с помощью Photon Pun2 или Photon Chat?

Я использую оба пакета Photon Pun2 и Photon Chat в своем приложении. Но я не могу найти способ отправлять или получать изображения, аудио или видео через личное сообщение.


person Arslan Mughal    schedule 17.05.2021    source источник


Ответы (2)


Да есть... Однако она достаточно ограничена.

Насколько велики вещи, которые вы должны отправить?


Чат

В Photon Chat полезная нагрузка сообщения ограничена чем-то между 400 000 и 500 000 байт. Я не проверял это более подробно, но если размер вашего сообщения достигает определенного предела, вы немедленно отключаетесь без надлежащей обратной связи по причине ^^

См. введение в Photon Chat.

Пример

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 в любом случае сделает это со всеми параметрами, но если вы уже точно знаете, какие данные вы отправляете и как их десериализовать, гораздо эффективнее сделать это самостоятельно, например. в потоке/задаче. Затем на стороне получателя я снова десериализовал их в индивидуальную информацию.

person derHugo    schedule 18.05.2021

Это возможно и работает нормально (хотя вы должны следить за ограничениями, как сказал @derHugo). Моя реализация использует RPC для отправки массива байтов с помощью Texture2D.EncodeToPNG, а затем декодирование его на клиентах при получении.

Чтобы преобразовать массив байтов обратно в изображение, вы можете использовать Texture2D.LoadImage. метод.

Подход аналогичен отправке других типов мультимедиа, отличаются только методы кодирования/декодирования.

person Shomz    schedule 18.05.2021