Marmalade SDK 5.1.0 response data size?

bada
edited July 2011 in Native
Hi,

I try to send in join response game props
there is datalike 40x50 * sizeof(int)

And there is an error when I send data back
IwAssert failure (S3E, 96).
Message: got unknown socket error: 10040

Callstack:
_IwGxInitPipeline

its look like
WSAEMSGSIZE
10040
Message too long.

A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself.

Comments

  • Hi.
    The maximum command size on the Marmalade clients is 1.200 bytes. You are trying to send an operation with a size of 8.000bytes payload + a few bytes overhead. This means, the operation is not fitting into one command and will be split up into 6 of them or at least it should be split up into multiple commands. Your error indicates, that the splitting seems not to work correctly in your case.
    I will have a look into it tomorrow.

    Some additional info on sending big chunks of data:
    - In case, that you are sending this data as unreliable, you should be aware of, that all operations, that do not fit into a single command, will be sent reliable, even if they are flagged as unreliable, as the operation could not be reconstructed on the recieving side, if a part gets lost.
    - The overall size of an operation, supported by the protocol, is USHORT_MAX (depending on the kind of data, you are sending, the avaiable payload will vary as this is including all overhead like types, element-counts, string-lengths, etc.). If you ever want to send more than that, than you will have to split it up into multiple operations.
  • btw.: What do you mean with 5.1.0?
    There has never been a Marmalade SDK with that version number.
  • pretty sure it is exist
    http://www.madewithmarmalade.com/downloads

    or you mean Photon client for Marmalade? It is Photon-Marmalade_v6-5-4-RC2_SDK
  • bada wrote:
    pretty sure it is exist
    http://www.madewithmarmalade.com/downloads

    or you mean Photon client for Marmalade? It is Photon-Marmalade_v6-5-4-RC2_SDK
    Ah, sorry, yes, I thought, that you were talking about the Photon Client SDK version number, but of course you are right. As you only wrote Marmalade SDK and not a word about Photon or client in that name, tit should have been pretty clear to me, that you meant the version of the Marmalade, not of the Photon Client SDK for it :oops:
  • I can reproduce this in Marmalade simulator on Windows, but from the debug information it seems, that this is not a problem with Photon client, but with Marmalade's BSD-implementation, so we will contact them about this issue and inform you, if there are any news about it.
    Was this working fine for you before upgrading to 5.1.0?
  • i didn't try it on other versions, so don't know.
    But this is really a blocking bug for us, hope this would be fixed soon.
  • tested myself on 5.0.3 and on 5.1.0.beta1 now, got the same issue.
  • Successfully tracked it down to a deviation of the behavior of the Marmalade BSD-socket implementation in comparison to all other bsd-socket implementations, which we ever had to deal with, but luckily there is an easy workaround for this issue, so that we probably already can supply you with a bugfix release, addressing this issue, tomorrow evening, GMT.
  • thanks
  • I try it, it seems to work, but still sometimes crush socket when a big chunk of data sent.

    In trace of c++ client was something like alot of
    PHOTON: do not dispatch if that command is not the very next one available (this is reliable)
    
  • Do you send these big chunks only from the server or also from the client?
    Please make sure, that you call PhotonPeer::sendOutgoingCommands() often enough after putting a operation with a lot of data into the sendQueue of the client, as it will be fragmented into multiple udp-packets and only one packet will go out per call to this function (and it is just called once per PhotonPeer::service()-call). If you would for example try to get out one operation per PhotonPeer::sendOutgoingCommands(), but your operations are so big, that they will be split up into 2 or more fragments per operations, your local sendqueue will grow quickly and the operationsreceived by the server will be more and more out of date over time.
    Even if you just receive big chunks of data from the server, the client will still send out ackknowledgements to the server for every received fragment and these acks also need calls to PhotonPeer::sendOutgoingCommands() , to actually be sent. As yoo will only get informed via a regular callback, after the compelte operation response has got trough, you ca't know, when you have to call sendOutgoingCommands more often, to accelerate the procedure (however you will get warnings in the debug-callback, if a queue passes the warning-limit of 75 elements, when you set the photon-debug-level to at least WARNINGS and you will get iformed, whenever outgoing data from the client will be fragmented, if you set the level to at least INFO, so that you can check, if you call serviceBasic(), dispatchIncommingCommands() and sendOutgoingCommands() often enough). I would approach this sitaution by only sending minimal amounts of data in the operation response, but sending out an event with the big chunk right after that response to the according client. As soon as the client receives the response, it should call serviceBasic() and sendOutgoigCommands() more oftenuntil it receives the event.
  • I send data only from server. I'll try make serviceBasic() more often.
  • bada wrote:
    I send data only from server. I'll try make serviceBasic() more often.
    As the acks still have to go out, PhotonPeer::sendOutgoingCommands() probably also will need more calls when receiving a bit chunk of data.
  • There is another strange bug
    I get my data (40*50*int) as
    template<class T>
    	T*                  GetDataPtr(ExitGames::Hashtable * ht, const ExitGames::JString& key)
    	{
    		if(ht->getValue(ExitGames::KeyObject<ExitGames::JString>(key)))
    		{
    			return (T*)((ExitGames::ValueObject<T>*)ht->getValue(ExitGames::KeyObject<ExitGames::JString>(key)))->getDataAddress();
    		}
    		return NULL;
    	}
    
    
    // OnOperationJoin
    ExitGames::Hashtable * t = ((ExitGames::ValueObject<ExitGames::Hashtable>*)returnValues.getValue(ExitGames::KeyObject<nByte>((nByte)CNetwork::OP_JOIN_PARAM_GAMEPROPS)))->getDataAddress();
    	if (t != NULL)
    	{
    		int y = 0;
    
    		if(t->getValue(ExitGames::KeyObject<ExitGames::JString>("board")))
    		{
    			int ** b = tools::GetDataPtr<int*>(t, "board");
    			int w = tools::GetInt(t, "board_width");
    			int h = tools::GetInt(t, "board_height");
    			InitLevel(b, w, h);
    		}
    	}
    

    but sometimes its crash with
    Unhandled exception at 0x02562186 (gomoku.s86) in s3e_simulator_debug.exe: 0xC0000005: Access violation reading location 0x00000008.
    

    breaks in
    in ValueObject.h
    on
    template <>
    	inline Hashtable* ValueObject<Hashtable>::getDataAddress(void)
    	{
    		return (_type == EG_HASHTABLE && !_dimensions)?(Hashtable*)_data:0;
    	}
    

    it seems zero data there
    this happens if connect to server join room receive data? close game than fast connect again and join room again
  • Hmm, only sometimes? In that case it may help, if you can reproduce it, while having the debug level set to DEBUG and give me the output of both debugReturns (Common and Photon). Thanks.
  • here my debug log for mLitePeer->setDebugOutputLevel(DEBUG_LEVEL_ALL);

    http://www.everfall.com/paste/id.php?t7keeevj3ek3

    and baseListener never called;
  • Ok, this is not a client bug, this was in game logic bug - response from server with error and I didn't check return code, my fault sorry.
  • Also I have a question. If I rejoin room and there Is already actor from my previous join, how correctly handle this situation?
  • I would approach this situation by using an authentication-operation right after a successful connect: The clients sends a custom oepration to the server with some unique identifier. On iPhone the UDID is suited for this purpose, not sure about the ohter platforms supported by Marmalade. You could also use a login/password combination therefor.
    If the unique identifier is already online, there are a few options for you, how to handle it: a) just kick the old session, when a new successful authentication for that identifier happens, b) do not accept any new logins, until the old session logged out or timed out, c) as a modification of b a successful authentication could trigger an event sent to the peer, which is already online with that ID, which triggers a message-box there, with buttons for logout or rect the new login, of course a timeout will be handled as logout, but as long as the connection stays online you could give the old connection as many time to decide, as you want, d) allow multiple connects at the same time from the same device or with the same login (is very useful for example for instant-messagers, but less interesting for games).
    If you do not want to go with option d, then you never can join the same room like your previous join and if you go with d for the whole server, just use option a, b or c when actually joining ingame-rooms or allow players to join the same room with the same account multiple times, if you want that.