Search Unity

DarkRift - Fast and Flexible Cross Platform Networking

Discussion in 'Assets and Asset Store' started by Jamster, Apr 20, 2015.

  1. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    Cool, just wanted to make sure. Right, now what's the proper way to receive a message sent to the server, I've got DarkRiftAPI.SendMessageToServer() for sending the message and that's alright, but on the receiving end there's ConnectionService.onData and ConnectionService.onServerMessage.

    When using onData I get that I'm supposed to use DecodeData but I can't find it in the documentation and whenever I call the method on the received message it just spits out a bunch of errors.

    Then with onServerMessage I can use data.ToString if it's receiving a message from SendMessageToServer just fine, but then it spits out errors if I try print out data from SendMessageToOthers or SendMessageToAll. Is this expected behavior? Which one is recommended to use?

    I'm gonna be making an authoritative server so I'd only be using SendMessageToServer, I'm just curious.
     
  2. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Ah yes, that's still missing and I'd forgotten I was going to add that... Sorry!

    If you use SendMessageToServer it will trigger onServerMessage, all messages (including server messages) will trigger onData to which you need to call DecodeData if you want to get the data so that you are only decoding data when you actually need to (its quite expensive to do).

    You shouldn't however be getting errors :p Can you attach a log file with the errors in for me? Chances are it's just a simple serialization problem :)

    Aside: onData shouldn't be used for processing server messages, it's just there to allow you to validate messages before they are distributed to other clients, the fact that server messages actually trigger it was just me being an idiot when I wrote it...
     
  3. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    Well, disregard all that, the only reason it was throwing errors was because of the Vector3 in the tutorial plugin. So I'm guessing that the server doesn't recognize that data type, on that note can I store the raw encoded data somewhere, pass that data out to the clients at a later date and have them happily decode it? I ask because I don't know if you've got something like a time stamp on it, which now that I think about it wouldn't make sense at all, but then sometimes people create some pretty nonsensical stuff.
     
  4. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Ahh ok good :) No, the server doesn't recognise those datatypes unless you have the UnityEngine.dll referenced by your plugins, for datastructures as simple as that it's usually better to serialize them manually anyway :)

    Nope, it's fine to store the data as far as I know :) Though I'm not sure there's an easy way of getting it out :oops:
     
  5. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    It was a contingency plan I was thinking up, but realized it would just be easier to, as you said, serialize them manually. Alright one last question, maybe, probably not, we'll see. Is there any way to iterate over the connected clients without creating a list/array and adding/removing the id's as they connect and disconnect? It's easy enough to implement but I don't want to be going ahead and adding it in if the functionality is already there.

    Also how do I detect that a client's disconnected using ConnectionService.onServerMessage on the server, I have code in there that I don't really want to run when a player disconnects but it gets called regardless when a client calls the Disconnect method.
     
    Last edited: Feb 12, 2016
  6. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    DarkRiftServer.GetAllConnections() is what you want :)

    ConnectionServer.onPlayerDisconnected will be called when a player disconnects, onServerMessage should only be called when you specifically send a server message.
     
  7. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    Cool, that's exactly what I was after.

    As for onServerMessage it must be picking up the disconnect as well, because the only time I call SendMessageToServer in the client is in the Start method and then it receives another bit of data at the exact same time as when the client disconnects.

    13/2/2016 10:47:41 AM [Trace] Found a total of 1 plugins.
    13/2/2016 10:47:41 AM [Log] Timer initialised
    13/2/2016 10:47:41 AM [Log] Loaded plugin: Connection Manager Version: 1.0
    13/2/2016 10:47:47 AM [Log] Connected: 127.0.0.1:1788
    13/2/2016 10:47:47 AM [Log] Data received Sending from start: 5.682179,1.092185,-6.446707
    13/2/2016 10:47:53 AM [Log] Disconnected: 127.0.0.1:1788
    13/2/2016 10:47:53 AM [Log] Data received 0
     
  8. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Ahh yes, I'm actually wrong! The disconnect message is transmitted to All and therefore the server will receive it. The easiest thing to do is just ignore things with a tag of 255 (internal messages) :)

    Why did I think that was a good idea...? :oops:
     
  9. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    So if there's multiple clients up then they'll receive a disconnect message too and not just the server? Things to fix in #2 ;)
     
  10. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    You wont get it received at the clients, they don't pass it on to you. But actually yes they do need to receive that message in order for them to call onPlayerDisconnected, hence why I made it send to all... Presumably I just forgot it would trigger the server event... -_-

    Gah this is all so much simpler in DarkRift2... :p
     
  11. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    Random performance related question, how many messages do you think the server can handle when it's A) integrated with unity, and B) standalone. So for example, would there be lag if it was receiving 1000 messages every 0.5 seconds (what about 10,000), assuming the messages just contain say, a Vector3 and that it's being decoded each time. Also assuming that the computer the server is running isn't limiting its performance. More a question about the limitations of the software, since I can't really test it out with great success seeing as my hardware limits its capabilities.
     
    Last edited: Feb 15, 2016
  12. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    It's been a while since I've run a proper load test on it actually. If I recall correctly my crumby laptop was able to handle 1000 connections continuously transmitting very easily (I can't remember how many messages that was, I'd guess around 2000 per second). Obviously as soon as you add your own plugin code that will add some latency as you process through data, particularly when serializing and deserializing the data.

    I'll try and run more some more up to date load tests at some point, though I think I broke my load tester while upgrading it so it might take a while!
     
    Dark_Tiger likes this.
  13. TobiasKullblikk

    TobiasKullblikk

    Joined:
    Sep 26, 2014
    Posts:
    5
    Does this plugin support iOS, UWP & Android ?
     
  14. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    iOS and Android I'm fairly sure work but I think you'll need the pro versions if I recall correctly. Unity web player isn't, no.
     
  15. TobiasKullblikk

    TobiasKullblikk

    Joined:
    Sep 26, 2014
    Posts:
    5
    Universal Windows Platform (xboxone, winphone, windows) ?
     
  16. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    OK, I think the easiest thing for me to do is actually compile a list of platforms that are supported so...
    • Web player: No, sockets aren't supported in web player
    • PC, Mac & Linux Standalone: Yes!
    • iOS: Yes but need iOS Pro
    • Android: Yes but need Android Pro
    • Blackberry: Yes *
    • Windows Store: Yes *
    • Windows Phone 8: Yes *
    • Xbox 360: Yes *
    • Xbox One: Yes *
    • PS3: Yes *
    • PS Vita: Yes *
    • PS4: Yes *
    • Playstation mobile: Yes *
    • WebGL: No, sockets aren't supported.
    I've put asterisks (*) next to ones that I can't test yet but have no reason to believe wont work (for example I don't own a license to deploy to Xbox, nor do I own an Xbox ) :)
     
  17. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    DarkRift 1.4.1 has just been submitted to the Asset Store, hopefully it'll be up by the end of next week :)
     
  18. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
  19. Rurumi

    Rurumi

    Joined:
    Mar 1, 2015
    Posts:
    5
    Two questions about embedded server :(

    1. How do I create a plugin for embedded server?
    Should I create a solution as the tutorial said and then put the .dll in Unity(embedded server project)?
    Or can I just create a .cs file in Unity and inherit from DarkRift.Plugin class?

    2. How to execute commands in embedded server?
     
  20. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    You dont need to create a plugin for the embedded server, you can connect to the events and make calls directly from you normal Unity code :) If you really want to you can pass typeof(YourPlugin) into the bootstrap method in Server.cs :)

    There's no built in feature for that but you can use Interface.ExecuteCommand(string) to send them manual yourself and so you can then build your own UI for it :)
     
    Rurumi likes this.
  21. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    26
    I can't send my server over the internet :(. I'm guessing its because the plugin loaded is being given internet restriction. The error came up from loading the plugins from folder, and it gave a link to this. I can't copy the error message though. Is this intended (can't load plugin if it is sent over the internet)? Its very inconvenient since I would like to be able to put my server from a cloud and be able to work on it everywhere without using git all the time. (for the record, git works).
     
  22. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Hmmm... Well you're the first to have that error...

    You're absolutely right about what's causing it; it's not intended, just how .NET works internally.

    You can't plugins into a sandbox in DarkRift (actually might be able to in DarkRift 2!) so your only option really is to add the line into DarkRiftServer.exe.config, it should look like:
    Code (csharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <configuration>
    3.   <startup>
    4.     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    5.   </startup>
    6.   <runtime>
    7.     <loadFromRemoteSources enabled="true" />
    8.     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    9.       <probing privatePath="Lib;Plugins\Lib" />
    10.     </assemblyBinding>
    11.   </runtime>
    12. </configuration>
    Jamie
     
  23. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    DarkRift 1.4.1 is now out on the asset store :D

    Update contains bug fixes, an improved Server.cs and some fixed documentation :)
     
  24. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Turns out I forgot to copy the fixed documentation into the package when I submitted it so for anyone looking for informations on DecodeData, NetworkMessage or the Update method in plugins try the attached version instead :p
     

    Attached Files:

  25. InfiniteDice

    InfiniteDice

    Joined:
    Jun 30, 2015
    Posts:
    44
    Made a project to test DarkRift, I have the basic movement sync and everything works in that regard (based on the example player project with DarkRift)...

    Question is, if you want to have the game run persistent and generate and manage PVE elements, how is that done with an enclosed dll based server solution? Do I need to log a pseudo admin-client that controls all the PVE monsters/generates and manages inventories, etc? That's what I'm guessing, just seems a bit 'on the rocks' if said client decides to crash... Then all the assets belonging to that admin/client are despawned.

    Ideas?
     
  26. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Hi!

    I'm not sure I fully understand what you're asking but I think you're asking about ensuring data is stored between different users logging on/off?

    That's perfectly possible to do in a plugin. You just need to create member variables that store the data and then re-present that to any new users. Alternatively you could use a database to store things like inventory so that even if the server is turned off the users still retain their data (probably how you want to do that for almost all user data).

    If you need the features of Unity in your game (e.g. for navmesh/physics) I'd usually suggest just embedding the server into a Unity instance, that way you don't have to manage the separate permissions of an 'admin' client but you will get a performance penalty as Unity is only single threaded.

    Hope that helps :)

    Jamie
     
  27. InfiniteDice

    InfiniteDice

    Joined:
    Jun 30, 2015
    Posts:
    44
    Thanks, yeah I'll likely need to create a server/client as using just the dll server makes it difficult to keep a gameworld running when all the clients are logged off. As in, plants grow, creatures move around... even when nobody is watching :)

    So an admin client/server, then all the clients connect to that.
     
  28. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Do you mean embedded server? I.e. DarkRift runs inside a Unity instance or do you still mean a separate client that logs into the DarkRift server just to control things like that?

    Either way, it still sounds like you could do plant growth (creatures moving is a little harder) in a standalone server. :)
     
  29. FStar

    FStar

    Joined:
    Sep 11, 2015
    Posts:
    50
    How does the licensing work. Do I have to pay 100$ per server instance? or 100$ per game? So if my game has 3000 players and I host 6 servers, is the cost 600$ or 100$?
     
  30. InfiniteDice

    InfiniteDice

    Joined:
    Jun 30, 2015
    Posts:
    44
    I have a few more questions, is there any solution for caching the in-game objects?

    Example: player red joins, he spawns some blocks and makes a house.

    Player blue joins and he doesn't see player red's house because he wasn't online when the objects were called to spawn.

    Question: Is there a way to hold all spawned gameobjects and have them show up when a new player joins? A sort of snapshot of things being tracked?

    Lastly, is there any place to look at more advanced samples of Darkrift in regards to handling collisions or object management/ownership?

    Thanks :)
     
  31. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    It follows the Asset Store license in that respect, it would actually be 1 license per developer. If you host 6 servers and only have 1 developer it would be 1 license, if you host 6 servers and have 2 developers it would be 2 licences. (3000 users would need extreme licenses as you've suggested) :)

    Not built in... The best way to do that is in a server plugin record each block placement in a list (and database if you want a fully persistent world) and then in onPlayerConnected you'd send the list back to the new client :)

    Unfortunately there isn't really, I'd always hoped DarkRift would get a good following all posting their code but that hasn't really happened :( You can always post your code and people can tell you what you could improve or what might not work :)
     
  32. FStar

    FStar

    Joined:
    Sep 11, 2015
    Posts:
    50
    ok, great thanks.
     
  33. FStar

    FStar

    Joined:
    Sep 11, 2015
    Posts:
    50
    Hi again,

    I have the basics of a sandbox MMO game implemented in pure uNET currently with movement, streaming terrain, inventory management, some crafting, growing trees, terraforming and some other things and it's persisted in a database.

    Now I have started porting it to DarkRift. Not yet finally decided on a server solution, but just porting to some pure server solution is a good move for my game I think, and if it has been done once it will be easier to switch to some other solution later if needed.

    What concerns me so far is the lack of documentation and community for DarfRift. It was easy enough to create a server plugin, connect to server and send some messages but beyond that the documentation doesn't say much and I find the example code a bit strange. There are no samples for authoritative server implementations for example.

    In the client of demo code you do things like this:

    Code (csharp):
    1.  
    2. //Tell others that we've entered the game and to instantiate a player object for us.
    3.         if (DarkRiftAPI.isConnected)
    4.         {
    5.             //Get everyone else to tell us to spawn them a player (this doesn't need the data field so just put whatever)
    6.             DarkRiftAPI.SendMessageToOthers (TagIndex.Controller, TagIndex.ControllerSubjects.JoinMessage, "hi");
    7.             //Then tell them to spawn us a player! (this time the data is the spawn position)
    8.             DarkRiftAPI.SendMessageToAll (TagIndex.Controller, TagIndex.ControllerSubjects.SpawnPlayer, new Vector3(0f,0f,0f));
    9.         }
    10.  
    Why does the client send messages to other clients directly? Isn't that the server's job? How can clients even know who should have the messages?

    I have instead made my client calls to the server and then the server decides which clients should be calls and when.
    This is all fine, but is there a way I can tell the server never to accepts calls like the one's above? I feel that it is a security risk that it is even possible.

    I've also noticed for example that if I send messages from the OnPlayerConnect method on the server sometimes the messages get lost because the client is not yet really ready to receive them. Especially in debug mode on the client this happens, maybe because debug mode executes slower? Documentation needs to be better in this area, which order should you do things, in which method/event handler can I do which things etc.


    I will continue the implementation and see how it goes :) Please comment if you have some tips.
     
  34. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Unfortunately community isn't one of DarkRift Networking's strong points, I really hoped it would grow but it never really expanded that much :( Documentation wise I do need to add more, with DarkRift 2 in progress I'm perhaps a little too hesitant at doing much more work on DarkRift 1 (bar bugfixes etc.)

    I have an authoritative example in progress at the moment as it's been requested and hopefully that will be out within the next few weeks along with some more bugfixes I've found.

    You're absolutely right in that it's the server's job and any production game should respect that. The demos use the client to spawn the player to keep things simple, you could very easily move the spawning code into a server plugin (and have in the demo I am working on) but that would complicate the examples quite significantly and my thoughts were that it would put off a lot of new customers when they're trying to understand the very basics.

    You can subscribe to the onDistribute event in ConnectionService and return a boolean as to whether the server should distribute something or not to stop things like that :)

    That's one of the bug fixes I have ready to release! :) I'll try and also improve the documentation for that

    Jamie
     
  35. FStar

    FStar

    Joined:
    Sep 11, 2015
    Posts:
    50
    Thanks for the quick answer and good answers to the questions. I will block this is onDistribute then as you said.

    Thanks again!
     
  36. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    I don't know if this has been asked/addressed, but how scalable, server-side, is DarkRift? I'm wanting to use different physical machines for different functions, but all presenting as a single server. Is it possible, within DarkRift, to authenticate by sending input to one IP, then 'hand off' the connection to another machine to manage, say, character information?
     
  37. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    It's not so easy with the current DarkRift (hopefully DarkRift 2 will be adding some functionality for this). The closest you could do would be to pass data around using a database (eg have an authentication key that they can use to confirm they are the same client). You could also do similar with a DarkRift server that all the other servers connect to to share data.

    Sorry there's not more for that, there hopefully will be soon :)

    Jamie
     
  38. Conquestor2

    Conquestor2

    Joined:
    Aug 17, 2015
    Posts:
    5
    Will darkrift 1/2 play nicely together?

    I've been working on a project, and have a mail server/chat server/sharded game server (chunk loading terrain)/login server/proxy server all working based on Darkrift 1.

    The simple API/architecture is fantastic, especially to catch messages outside of Unity, and is probably the best tool to make an authoritative Unity game (using server-sided unity physics) while also handling communication outside of the game client.

    In my use case, that allows me to use Unity physics, and my own custom server for mostly everything else, passing it through a proxy server to a completely different server than the one Unity's hosted on.
     
  39. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    I have a solution that sometimes works, but other times the DarkRift server throws an error: A connection was forcibly closed, error code: 10054

    Any pointers on what is going wrong? It's tricky to debug since it only happens some of the time.
     
  40. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Unfortunately not, though the conversion wont be too hard as it's mostly small API changes. I'm going to write a guide on this :) The conversion for Unity may be a little harder just as things aren't as similar between the versions for that, the new version will be a lot better for Unity though :)

    It would be good if you could attach a log of it, I think it may be sorted next version but I'm not sure.

    Jamie
     
  41. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    Not sure if this is super helpful, but see attached.
     

    Attached Files:

    Jamster likes this.
  42. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Thanks :) I take it that's occurring when you actually disconnect/close the application rather then occurring randomly?

    If that's the case can I double check you've got a Disconnect call in OnApplicationQuit somewhere? :)

    Jamie
     
  43. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    Yup! It occurs when I disconnect/close the application in the editor.

    I do have a Disconnect call OnApplicationQuit :/
     
  44. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Hmmm ok, I'll check through the code my end :) Thanks :)
     
  45. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    Another detail: this error most commonly happens when the connection seemingly failed to open in the first place.

    What should happen, IMO, is:

    1. Client connects to server (Connection is opened)
    2. Client receives messages
    3. Client disconnects (Connection is closed)

    What sometimes happens is that the client fails to realize that it is connected and doesn't receive messages. Then when it closes the connection, it gets the socket error.

    It's weird because my server logs say that the client is indeed connected.

    Edit: just to clarify,

    1. Server is sending messages to client
    2. Client is listening
    3. But client does not receive messages from server
     
    Last edited: Apr 4, 2016
  46. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Oh right, that is interesting :S Does the client's isConnected return true when this happens/Can you send from the client?

    Thanks for the extra information

    Jamie
     
  47. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    If you're referring to the client's "DarkRiftAPI.isConnected" yes this returns true during the error case.
     
  48. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Well I've redone a lot of the error catching on the sockets and so hopefully we may have a fix for these problems! Just want to test more thoroughly and then I'll do a docs update and submit the the store hopefully within the week.
     
  49. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    @Lisk, Can you turn private messages on? Just want to run the latest server past you to see if you still have issues :)
     
  50. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    @Jamster I think I got your email - thank you for checking!

    Another question I have: do you have a recommended approach for validating arguments?

    For example, I'm writing a server plugin that receives some data. I want to check that I am receiving an Int and not a string (for example). Or that I have 3 arguments rather than 2 or 25.

    • Is it recommended to just attempt to ReadInt from the DarkRiftReader and check each value as I deserialize it?
    • Or should I just wrap everything in a Try/Catch?
    • Or something else?