Send custom data type with sendDirect

benjaml
benjaml
edited September 2019 in Native
Hello,

I was wondering if I can use a custom data type to send my data along sendDirect ?

Here is my data

struct P2PPacket
{
public:
//const void* PubData;
int CubData;
EP2PSend P2PSendType;
};

this looks like a composition of allowed types but It does not accept it and I got the ASSERTION_FAILED_ERROR_UNSUPPORTED_VALUE_TYPE error.

I would like to know if I can use custom data types to use along with sendDirect. I would also like to know how I can convert my void* to an allowed photon type.

Comments

  • Kaiserludi
    Kaiserludi admin
    edited September 2019
    Hi @benjaml.

    Yes, it is possible to send custom data.
    You have the following options to do so:
    a) read the member variables out of the custom class one by one and store them in one of Photons containers
    b) serialize the data into a byte array yourself and just pass that array to Photon.
    c) register your class with Photon as a custom type - once you have done this, you can simply pass objects of that class to Photon for sending

    From how your question is phrased I assume that you are interested in more information about case c).
    A custom type needs to inherit from Common::CustomType<nByte typeCode> and implement the following pure virtual functions from Common::CustomTypeBase:
    
    virtual void cleanup(void) = 0;
    virtual bool compare(const CustomTypeBase& other) const = 0;
    virtual void duplicate(CustomTypeBase* pRetVal) const = 0;
    virtual void deserialize(const nByte* pData, short length) = 0;
    virtual short serialize(nByte* pRetVal) const = 0;
    
    Furthermore you need to subclass Common::CustomTypeFactory<nByte typeCode> with the matching type code and implement the following pure virtual functions of it in a factory class that Photon will use to create instances of your custom type:
    
    virtual CustomTypeFactory<typeCode>* copyFactory(void) const = 0;
    virtual void destroyFactory(void) = 0;
    virtual CustomType<typeCode>* create(short amount) const = 0;
    virtual CustomType<typeCode>* copy(const CustomType<typeCode>* pToCopy, short amount) const = 0;
    virtual void destroy(const CustomType<typeCode>* pToDestroy) const = 0;
    virtual unsigned int sizeOf(void) const = 0;
    
    Note that the typeCode is used to identify the custom class and each custom class should use a different typeCode.

    You can find a simple example implementation of a Photon custom type in demo_typeSupport, which is part of the Client SDK.
    Look for the classes SampleCustomType and SampleCustomTypeFactory in the demo code for examples on how to implement all those functions.

    Please read the API reference for the classes CustomType, CustomTypeBase and CustomTypeFactory for further information:
    https://doc-api.photonengine.com/en/cpp/current/html/a00057.html
    https://doc-api.photonengine.com/en/cpp/current/html/a00058.html
    https://doc-api.photonengine.com/en/cpp/current/html/a00059.html

    Note that if you want to use custom types in custom operations with a self-hosted server or with Photon Enterprise Cloud and the server needs to actually process those types in those operations, then you need to register those custom types on the server as well. When you use them with sendDirect() or with opRaiseEvent() or with custom operations in which they are just relayed to another client, then only the sending and the receiving client need to register them.
  • benjaml
    benjaml
    edited September 2019
    So I made my custom type and my customTypeFactory, but it seams something not quite right yet. My CustomType and CustomTypeFactory is properly registered, I can break into the serialize function of my customtype.

    But sendDirect is always returning me false. I've seen that serialize can pass a null pointer in the parameters, as I do not call it myself, is it normal that photon provides a null pointer for serialize of my custom type.

    Is there a way to get the information (logs) of what goes wrong ? maybe I did not setup right my logs.
  • Hi @benjaml.


    I've seen that serialize can pass a null pointer in the parameters, as I do not call it myself, is it normal that photon provides a null pointer for serialize of my custom type.

    Yes, that is perfectly normal. Some of the calls to this function only call it to find out in how many bytes the serialization will result, so they are only interested in the return value, but don't need the function to actually store anything in the provided array. To indicate that these calls pass NULL so that the function does not need to do unnecessary work.


    But sendDirect is always returning me false.

    This is unrelated to custom types.
    A return value of 'false' usually indicates that no direct connection to the addressee exists and the 'fallbackRelay' parameter has not been set to 'true' and hence the data could not be sent. Another reason for it to return 'false', is that the size of your message has exceeded the maximum size of 1200 bytes.


    Is there a way to get the information (logs) of what goes wrong ? maybe I did not setup right my logs.

    Do you see any logging at all?
    The logs are sent to your implementation of debugReturn() in the class that you have passed in as Listener.
    Please make sure that your logging level is set high enough, that you have not defined EG_NOLOGGING and that your debugReturn() implementation actually prints the received strings to the location where you look for them.
  • benjaml
    benjaml
    edited September 2019
    I did indeed set the relayfallback to true. The target player is maybe wrong, right now the targetPlayer is set to 1, is it a normal value ?

    I've also tried to make a simple sendDirect call and it also returns me false
    loadBalancingClient.sendDirect< int>(2, ExitGames::Common::JVector< int>(), true);

    I've tried to put the logging level to ALL but I do not have any information of what could have gone wrong

    I'm currently alone in the room si I'm trying to send me a direct message, which will fail, but (if I've understand well) with the relayFallback set to true, it should send it as an event, but maybe it will return false even if it send it as an event

    I do not get anything to come in customEventAction so I think that the fallback did also failed

    after some digging, it seems that it does not correctly do the fallback as I've done it manualy if the send direct fails and it did work. So I think that I did not understand well the use of the fallback
  • Hi @benjaml.


    right now the targetPlayer is set to 1, is it a normal value ?

    The player numbers are increasing values in the order in which the players enter the room. Hence the number of the creator of the room is 1, the number of the first client to join it is 2, and so on. So yes, as you try to send the message to yourself, the target number of 1 is correct, if you are trying to send the message from the client that has created the room.


    I've also tried to make a simple sendDirect call and it also returns me false
    loadBalancingClient.sendDirect< int>(2, ExitGames::Common::JVector< int>(), true);

    That code instructs Photon to send the message to everyone else in the room except from the sender. Naturally when the sender is the only client in the room, there will be no receivers, so this is expected to return false in that case.


    but maybe it will return false even if it send it as an event

    It will return 'true' in that case.


    I do not get anything to come in customEventAction so I think that the fallback did also failed

    Messages that are sent through the fallback relay option are always sent reliably, so they either reach the receiver or the connection will be considered lost.
    However in your case sendDirect() returned 'false', so the message did not get sent in the first place.


    I'm currently alone in the room si I'm trying to send me a direct message, which will fail, but (if I've understand well) with the relayFallback set to true, it should send it as an event

    I have just reviewed the implementation code in this regards and this is apparently not the case.
    sendDirect() will never send a message to the local client, not even via the fallback relay.

    This is a bug in the current implementation and we will fix it with the next release.
  • Hi @benjaml.

    4.1.15.0 has been released today.