complex messages in chat

In the intro to photon chat it says

"Photon Chat allows you to define complex messages, e.g. for invitations."

Are there any code examples for this?

Also, my understanding is that a channel is deleted when there is no one left in there. I'm trying to create a persistent chat so I'm saving all messages to a database and plan on loading and displaying some recent ones when users first connects to the chat - is this the right approach? If so, how do you then append new messages to the text box? The chat example that comes with PUN just overwrites the whole text box with

this.channelText.text = channel.ToStringMessages();

This would obviously break the approach I'm considering for persistence (because it would overwrite the old, loaded from the db messages) and doesn't take into account complex messages I asked about at the start. Is it better to somehow loop through the messages parameter in OnGetMessages and only display new ones?

Thanks in advance

Comments

  • BigGameCo
    BigGameCo
    edited May 2018
    I got all this working so no help required. If anyone else is stuck on this, here's what I discovered after posting this thread:

    1. The example provided for OnGetMessages is not very good. It's better to loop through the senders or messages array and process them manually.
    2. OnGetMessages only gets passed new messages as they come in - this wasn't clear from the provided example
    3. I use this to serialize the complex messages.
    public byte[] SerializeMessageWrapper(ChatMessageWrapper chatMessage){
    		BinaryFormatter bf = new BinaryFormatter();
    		MemoryStream ms = new MemoryStream();
    		bf.Serialize(ms, chatMessage);
    		byte[] myByteArray = ms.ToArray();
    		byte[] compressed = Compress(myByteArray);
    		return compressed;
    	}
    
    	public ChatMessageWrapper ByteArrayToMessageWrapper(byte[] messageBytes){
    		byte[] decompressed = Decompress(messageBytes);
    		MemoryStream memStream = new MemoryStream();
    		BinaryFormatter binForm = new BinaryFormatter();
    		memStream.Write(decompressed, 0, decompressed.Length);
    		memStream.Seek(0, SeekOrigin.Begin);
    		ChatMessageWrapper chatMessage = (ChatMessageWrapper) binForm.Deserialize(memStream);
    		return chatMessage;
    	}
    
    	public static byte[] Compress(byte[] raw){
    		using (MemoryStream memory = new MemoryStream()){
    			using (GZipStream gzip = new GZipStream(memory,
    				CompressionMode.Compress, true)){
    				gzip.Write(raw, 0, raw.Length);
    			}
    			return memory.ToArray();
    		}
    	}
    
    	static byte[] Decompress(byte[] gzip){
    		// Create a GZIP stream with decompression mode.
    		// ... Then create a buffer and write into while reading from the GZIP stream.
    		using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress)){
    			const int size = 4096;
    			byte[] buffer = new byte[size];
    			using (MemoryStream memory = new MemoryStream()){
    				int count = 0;
    				do{
    					count = stream.Read(buffer, 0, size);
    					if (count > 0){
    						memory.Write(buffer, 0, count);
    					}
    				}
    				while (count > 0);
    				return memory.ToArray();
    			}
    		}
    	}
    ChatMessageWrapper is just my custom object used for storing all the properties of the complex messages.

    Then I send messages with something like this.
    public void SendFriendlyBattleRequest()
    	{
    		if (this.chatClient != null)
    		{
    			ChatMessageWrapper messageWrapper = new ChatMessageWrapper();
    			messageWrapper.messageType = (int)MessageType.BattleRequest;
    			FriendlyBattleRequest friendlyBattleRequest = new FriendlyBattleRequest();
    			friendlyBattleRequest.channelID = chatChannel;
    			friendlyBattleRequest.someVar = "hi";
    			messageWrapper.message = friendlyBattleRequest;
    			this.chatClient.PublishMessage(chatChannel,SerializeMessageWrapper(messageWrapper) );
    			StartCoroutine(AddChatMessageToDatabase(messageWrapper));
    		}
    	}
    And process the messages with something like this
    public void OnGetMessages(string channelName, string[] senders, object[] messages)
    	{
    		if (channelName.Equals(chatChannel))
    		{
    			
    			for(int i = 0; i< senders.Length;i++){
    				ChatMessageWrapper messageWrapper = ByteArrayToMessageWrapper((byte[])messages[i]);
    				messageWrapper.message.sender = senders[i];
    				 if(messageWrapper.messageType == (int)MessageType.BattleRequest){
    					clanUI.AddFriendlyBattleMessage((FriendlyBattleRequest)messageWrapper.message);
    				}
    
    		
    		}
    	}
    Hopefully that will save someone some time...
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @BigGameCo,

    Thank you for choosing Photon!

    You asked a lot of questions in your post.

    The code examples are scarce but now thanks to you there are more code snippets.
    To achieve channels history persistence we offer chat webhooks.
    What we mean by complex chat messages is that a message can be of any type and data structure (not only text string). The only condition here is that the data can be Photon serializable. You can also register a custom type if you want to. Read more here.