Placeholder-Software / Dissonance

Unity Voice Chat Asset
71 stars 5 forks source link

[bug] Error ID: Hash collision between room names '{0}' and '{1} #227

Closed lucas-brasmobi closed 3 years ago

lucas-brasmobi commented 3 years ago

Context

The error [Error ID: Hash collision between room names '{0}' and '{1}] occurs on the client, when the server has more than 2k of users connected.

Error Log:

[Dissonance:Core] (01:18:36.864) Rooms: Error: 2_ryUwoglru! This is probably a bug in Dissonance, we're sorry! Please report the bug on the issue tracker "https://github.com/Placeholder-Software/Dissonance/issues". You could also seek help on the community at "http://placeholder-software.co.uk/dissonance/community" to get help for a temporary workaround. Error ID: Hash collision between room names '{0}' and '{1}'. Please choose a different room name.
UnityEngine.Debug:LogError (object)
Dissonance.Logs/LogMessage:Log () (at Assets/Plugins/Dissonance/Core/Log.cs:69)
Dissonance.Logs:SendLogMessage (string,Dissonance.LogLevel) (at Assets/Plugins/Dissonance/Core/Log.cs:98)
Dissonance.Log:WriteLog (Dissonance.LogLevel,string) (at Assets/Plugins/Dissonance/Core/Log.cs:181)
Dissonance.Log:Error (string) (at Assets/Plugins/Dissonance/Core/Log.cs:425)
Dissonance.Log:AssertAndLogError<string> (bool,string,string,string) (at Assets/Plugins/Dissonance/Core/Log.cs:567)
Dissonance.RoomIdConversion:ToRoomId (string) (at Assets/Plugins/Dissonance/Core/RoomIdConversion.cs:25)
Dissonance.Networking.RoomClientsCollection`1<System.Nullable`1<Dissonance.Integrations.MirrorIgnorance.MirrorConn>>:Add (string,Dissonance.Networking.ClientInfo`1<System.Nullable`1<Dissonance.Integrations.MirrorIgnorance.MirrorConn>>) (at Assets/Plugins/Dissonance/Core/Networking/RoomClientsCollection.cs:29)
Dissonance.Networking.BaseClientCollection`1<System.Nullable`1<Dissonance.Integrations.MirrorIgnorance.MirrorConn>>:JoinRoom (string,Dissonance.Networking.ClientInfo`1<System.Nullable`1<Dissonance.Integrations.MirrorIgnorance.MirrorConn>>) (at Assets/Plugins/Dissonance/Core/Networking/BaseClientCollection.cs:176)
Dissonance.Networking.BaseClientCollection`1<System.Nullable`1<Dissonance.Integrations.MirrorIgnorance.MirrorConn>>:ProcessClientState (System.Nullable`1<Dissonance.Integrations.MirrorIgnorance.MirrorConn>,Dissonance.Networking.PacketReader&) (at Assets/Plugins/Dissonance/Core/Networking/BaseClientCollection.cs:216)
Dissonance.Networking.BaseClient`3<Dissonance.Integrations.MirrorIgnorance.MirrorIgnoranceServer, Dissonance.Integrations.MirrorIgnorance.MirrorIgnoranceClient, Dissonance.Integrations.MirrorIgnorance.MirrorConn>:ProcessReceivedPacket (System.ArraySegment`1<byte>) (at Assets/Plugins/Dissonance/Core/Networking/BaseClient.cs:304)
Dissonance.Networking.BaseClient`3<Dissonance.Integrations.MirrorIgnorance.MirrorIgnoranceServer, Dissonance.Integrations.MirrorIgnorance.MirrorIgnoranceClient, Dissonance.Integrations.MirrorIgnorance.MirrorConn>:NetworkReceivedPacket (System.ArraySegment`1<byte>) (at Assets/Plugins/Dissonance/Core/Networking/BaseClient.cs:249)
Dissonance.Integrations.MirrorIgnorance.MirrorIgnoranceClient:OnMessageReceived (Mirror.NetworkConnection,Dissonance.Integrations.MirrorIgnorance.DissonanceNetworkMessage) (at Assets/Dissonance/Integrations/MirrorIgnorance/MirrorIgnoranceClient.cs:58)
Mirror.MessagePacking/<>c__DisplayClass5_0`2<Dissonance.Integrations.MirrorIgnorance.DissonanceNetworkMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Runtime/MessagePacking.cs:116)
Mirror.NetworkConnection:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Runtime/NetworkConnection.cs:156)
Mirror.NetworkConnection:TransportReceive (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Runtime/NetworkConnection.cs:191)
Mirror.NetworkClient:OnDataReceived (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Runtime/NetworkClient.cs:276)
kcp2k.KcpTransport:<Awake>b__13_2 (System.ArraySegment`1<byte>) (at Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs:60)
kcp2k.KcpClient:<Connect>b__6_1 (System.ArraySegment`1<byte>) (at Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpClient.cs:45)
kcp2k.KcpConnection:TickIncoming_Authenticated (uint) (at Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpConnection.cs:326)
kcp2k.KcpConnection:TickIncoming () (at Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpConnection.cs:367)
kcp2k.KcpClient:TickIncoming () (at Assets/Mirror/Runtime/Transport/KCP/kcp2k/highlevel/KcpClient.cs:89)
kcp2k.KcpTransport:ClientEarlyUpdate () (at Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs:117)
Mirror.NetworkClient:NetworkEarlyUpdate () (at Assets/Mirror/Runtime/NetworkClient.cs:1204)
Mirror.NetworkLoop:NetworkEarlyUpdate () (at Assets/Mirror/Runtime/NetworkLoop.cs:182)
martindevans commented 3 years ago

This is error is caused by having too many unique room names. Dissonance uses a 16 bit ID (calculated as the hash of the room name) for each room - this error indicates that two rooms were assigned the same ID.

With a normal number of rooms this isn't an issue - in fact you're the first person to ever report this! I assume you are generating hundreds or even thousands of rooms?

lucas-brasmobi commented 3 years ago

Exactly, We use it in 2D card game. We have 30k DAU. Matches are played by 2 or 4 players. A room is created for each match. It can generate up to 15 thousand rooms per day. How can we solve this?

martindevans commented 3 years ago

The real issue here is simply that Dissonance really isn't designed for rooms of this scale. Ideally all of the players would be split up into separate network sessions, so Dissonance is only handling 2-4 players instead of 2000! In the longer term I would recommend trying to do this, there is a lot of unnecessary network traffic flowing around to organise a voice chat session with 2000 people in it!

However, I understand that's probably a pretty big change for your game, so here's a workaround instead. As mentioned above Dissonance room names are identified by 16 bit IDs so there's a hard limit of 65535 rooms (2^16), however you're hitting this at much lower numbers because the chance of a collision increases the more rooms you have active. Instead of randomly generating room names (which might cause collisions) you can instead have the server hand out room names which are guaranteed not to collide. Here is a list of 65535 rooms names which will not generate a single hash collision:

https://gist.githubusercontent.com/martindevans/1c2d5edeee2f29e8ecba24e8ffde96d6/raw/ae7a909d6eb18e3a45c6d31b92df100344a819be/gistfile1.txt

This increases your limit from ~2000 concurrent matches (based on random chance it may be higher or lower) to exactly 65535 concurrent matches (this cannot be increased further without changing the underlying network protocol).

martindevans commented 3 years ago

Since I haven't heard back from you for a while I'll assume that fix worked for you. Don't hesitate to contact me again if you've still got an issue :)