Some troubles implementing Stream

Options
SPF
SPF
edited February 2021 in Photon Bolt
1 Do I need to CreateStreamChannel twice on the client which also play as server?
I used to use "event" to transfer data. Using event, I wrote code as if the server and the client are separated, meaning even on the client that play as server, it has to send and received event data from/to server. Do I need to do this too when create stream channel?
2 Can I use a same channel name for deferent client? For example, stream channel between client A and server and stream channel between client B and server are both created with the same name, is it OK? If the answer to question 1 is true, then should I use different names and keep the references of each UdpChannelName separately?
3 It gives null exception when I tried calling "BoltNetwork.Server.StreamBytes" on the client that also plays a server role. What is the proper way to do? Do I need to find out each BoltConnection with the targeted user that I want to send data to and then call StreamBytes on the connection?

Comments

  • ramonmelo
    Options
    Hello,

    Please, read the details here: https://doc.photonengine.com/en-us/bolt/current/in-depth/streaming-bytes
    1 Do I need to CreateStreamChannel twice on the client which also play as server?
    I used to use "event" to transfer data. Using event, I wrote code as if the server and the client are separated, meaning even on the client that play as server, it has to send and received event data from/to server. Do I need to do this too when create stream channel?

    No, you setup the stream channel per Bolt instance. So, you only need to setup 1 channel in this case.
    2 Can I use a same channel name for deferent client? For example, stream channel between client A and server and stream channel between client B and server are both created with the same name, is it OK? If the answer to question 1 is true, then should I use different names and keep the references of each UdpChannelName separately?

    No problem to use the same channel, you can receive data from multiples remotes using the same channel.
    About the usage of multiple channels, that is up to you.
    3 It gives null exception when I tried calling "BoltNetwork.Server.StreamBytes" on the client that also plays a server role. What is the proper way to do? Do I need to find out each BoltConnection with the targeted user that I want to send data to and then call StreamBytes on the connection?

    I think you are confusing concepts here.

    If you run as the server, you are the server, and nothing more. The only extra thing in your case, is that you are also spawning a player for the server, this does not mean it's a client in Bolt terms.

    Read here: https://doc.photonengine.com/en-us/bolt/current/connection-and-authentication/server-client-model

    Yes, you need a reference for the target connection in order to send data using the Stream System. You can easily get it from the "BoltNetwork.Clients" (https://doc-api.photonengine.com/en/bolt/current/class_bolt_network.html#aea312d0125d97ccdb141fd16ceeb5e5e ), for example.

    --
    Ramon Melo
    Photon Bolt Team
  • SPF
    SPF
    edited February 2021
    Options
    @ramonmelo Thank you!
    1 Now I can send stream data from server to clients, but not to the "Player" that's on the server, since the connection is null. Should I just call a function to "mimic the streaming"? This is what I meant for the question 1 in the above, that when I used events, the server also need to send event to the player even if the player is spawned on the server itself.
    2 As you sugguested, I call token.ToByteArray() to get the bytes data. When I tried with small amount of data, the streaming works. But when I changed it to a bit larger(around 4K), it gave out an error:
    IndexOutOfRangeException: Index was outside the bounds of the array.
    UdpKit.UdpPacket.WriteByteAt (System.Byte[] data, System.Int32 ptr, System.Int32 bits, System.Byte value) (at <3b70186b2acf40be8ab61e759b585166>:0)
    UdpKit.UdpPacket.InternalWriteByte (System.Byte value, System.Int32 bits) (at <3b70186b2acf40be8ab61e759b585166>:0)
    UdpKit.UdpPacket.WriteUInt (System.UInt32 value, System.Int32 bits) (at <3b70186b2acf40be8ab61e759b585166>:0)
    UdpKit.UdpPacket.WriteInt (System.Int32 value, System.Int32 bits) (at <3b70186b2acf40be8ab61e759b585166>:0)
    UdpKit.UdpPacket.WriteInt (System.Int32 value) (at <3b70186b2acf40be8ab61e759b585166>:0)
    Card.Write (UdpKit.UdpPacket packet) (at Assets/_Scripts/Model/Card.cs:34)
    Bolt.ProtocolTokenUtils.WriteToken (UdpKit.UdpPacket packet, Bolt.IProtocolToken token) (at <ed5388b742a94b18b9b7f386d8d06b96>:0)
    Player.Bolt.IProtocolToken.Write (UdpKit.UdpPacket packet) (at Assets/_Scripts/Model/Player.cs:120)
    Bolt.ProtocolTokenUtils.WriteToken (UdpKit.UdpPacket packet, Bolt.IProtocolToken token) (at <ed5388b742a94b18b9b7f386d8d06b96>:0)
    PlayersInfoEventToken.Bolt.IProtocolToken.Write (UdpKit.UdpPacket packet) (at Assets/_Scripts/Tokens/PlayersInfoEventToken.cs:51)
    Bolt.ProtocolTokenUtils.ToByteArray (Bolt.IProtocolToken token) (at <ed5388b742a94b18b9b7f386d8d06b96>:0)

    The code of Slot.Write:
    public void Write(UdpPacket packet)
        {
            packet.WriteInt(unitId);
            packet.WriteByte(actorId);
            packet.WriteInt((int)coord.x); // This is where the error appears, I printed it out, and the value of (int)coord.x is 1
            packet.WriteInt((int)coord.y);
        }
    

    The error occurred when the byte[].length is over around 924 to 960. (I tested it manually as precise as I could)
  • ramonmelo
    Options
    Hi @SPF ,
    1 Now I can send stream data from server to clients, but not to the "Player" that's on the server, since the connection is null. Should I just call a function to "mimic the streaming"? This is what I meant for the question 1 in the above, that when I used events, the server also need to send event to the player even if the player is spawned on the server itself.

    Again, that is up to you how you will handle the stream of the local player.
    If you already have the data, you can just send it right away without Bolt.
    2 As you sugguested, I call token.ToByteArray() to get the bytes data. When I tried with small amount of data, the streaming works. But when I changed it to a bit larger(around 4K), it gave out an error:

    The Stream works, either way, that is not an issue with the Stream System.
    The suggestion to use the Protocol Token was just to simplify the serialization to a byte array, but as the Token is directly related to the usage with the internal packaging system, they have a pre-defined size, which does not scale at will.

    If you need to serialize an arbitrary size of data, you will need to build your own serialization system or leverage another already existent one, like Protocol Buffers: https://developers.google.com/protocol-buffers

    --
    Ramon Melo
    Photon Bolt Team
  • SPF
    SPF
    edited February 2021
    Options
    Oh, thank you very much! I though I could change the size limitation of tokens. I'll write my own serialization codes, no problem :)

    You've been very helpful! <3