Search Unity

  1. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice
  2. We're running great holiday deals on subscriptions, swag and Asset Store packages! Take a peek at this blog for more information!
    Dismiss Notice
  3. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  4. Unity 2017.2 is now released.
    Dismiss Notice
  5. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  6. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  7. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  8. Unity 2017.3 beta is now available for download.
    Dismiss Notice

DarkRift - Fast and Flexible Cross Platform Networking

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

  1. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Ugh... :/ If you send the code over I'll try and have a quick look when I'm free.
     
  2. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    @Jamster I'm having trouble reproducing the bug, but it has happened more than once to me. I'll keep all my logs open and if I get it again I'll give you some data about it.
    Another question: In my server, I'm trying to create and send messages to my clients. What I did was this :

    Code (CSharp):
    1. Dictionary<int, PlayerInfo> theClients = new Dictionary<int, PlayerInfo>();
    2. foreach (KeyValuePair<int, PlayerInfo> theKey in theClients)
    3. {  DarkRiftServer.GetConnectionServiceByID((ushort)theKey.Key).SendReply(NetworkingTags.Controller, NetworkingTags.ControllerSubjects.StartGame, TotalPlayerData);
    4. }
    I've also tried
    Code (CSharp):
    1.                         foreach (KeyValuePair<int, PlayerInfo> theKey in theClients)
    2.                         {
    3.                             NetworkMessage newMessage = new NetworkMessage();
    4.                             newMessage.subject = NetworkingTags.ControllerSubjects.StartGame;
    5.                             newMessage.tag = NetworkingTags.Controller;
    6.                             newMessage.data = TotalPlayerData;
    7.                             newMessage.destinationID = (ushort)theKey.Key;
    8.                             newMessage.distributionType = DistributionType.ID;
    9.                             DarkRiftServer.GetConnectionServiceByID((ushort)theKey.Key).SendNetworkMessage(newMessage);
    10.                         }
    I get the proper client ID, which is 1, but when I send the reply, it doesn't reach the unity client. I've also tried making a new network message and sending it, but it didn't work. No error messages from the server or the client, and I know this code is definitely running properly. Its just not reaching client.

    I also tried using the DarkRiftServer.GetAllConnections() and sending the same message to each of them (assuming I have only one client connected it shouldn't matter) but its still not reaching.

    So the question would be how to properly send the messages.

    @GuilhermeStrice Try implementing the game in singleplayer first, then move to multiplayer. Multiplayer games generally take a parallel perspective and so is fundamentally different making them compared to singleplayer games. Take a look at the examples for DarkRiftNetworking given in the package. Those are a great starting point to learn how to multiplayer with DarkRift.

    For your Health thing, implementations differ based on code architecture. The below is only one way of implementing health. I'm going to make this simple and assume one unit in each client, so your screen would show two units (one from each client). Each client would be responsible for its own unit. I'll also make the assumption that if I press C, my client's unit will take damage.

    Below is untested code, but should work if you set the networking tags, networking subjects, and id properly.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using DarkRift;
    4.  
    5. public class unit : MonoBehaviour {
    6.  
    7.     float Health;
    8.     bool Controllable = false;
    9.     //We use this ID to identify which client this belongs to.
    10.     float id;
    11.     // Use this for initialization
    12.     void Start ()
    13.     {
    14.         Health = 100;
    15.  
    16.         //We send a message to all clients controller
    17.         //That this unit has joined the game.
    18.  
    19.         //Subscribe to the receive event. You should have another script that calls DarkRiftAPI.Receive() in the update. Only when you subscribe your function
    20.         //to the event and call DarkRiftAPI.Receive()  will things work properly.
    21.  
    22. //You did not have this in your screenshot. Are you missing this?
    23. //If you are missing this, also ensure that you have the script that calls receive.
    24. [B]        DarkRiftAPI.onDataDetailed += ReceiveData;[/B]
    25.  
    26.         //We tell other clients we have entered the game.
    27.         //They should spawn a unit on thier own and set the unit id to this client.
    28.         DarkRiftAPI.SendMessageToOthers(NetworkingTags.Controller, NetworkingTags.ControllerSubjects.JoinGame, null);
    29.     }
    30.  
    31.     // Update is called once per frame
    32.     void Update ()
    33.     {
    34.         if (Controllable)
    35.         {
    36.             //Press C to take damage
    37.             if (Input.GetKey(KeyCode.C))
    38.             {
    39.                 TakeDamage(10);
    40.             }
    41.         }
    42.     }
    43.  
    44.     void TakeDamage(float damage)
    45.     {
    46.         Health -= damage;
    47.         //Send message to each client to update that one unit's hp
    48.         DarkRiftAPI.SendMessageToOthers(NetworkingTags.Unit, NetworkingTags.UnitSubjects.UpdateHealth, Health);
    49.     }
    50.  
    51.     void ReceiveData(ushort senderID, byte tag, ushort subject, object data)
    52.     {
    53.         //This is where the data is received after it is sent.
    54.         //We check if this unit corresponds to the correct unit, marked by their ID.
    55.         if(senderID == id)
    56.         {
    57.             //Is it intended for the unit?
    58.             if(tag == NetworkingTags.Unit)
    59.             {
    60.                 //What is the message subject?
    61.                 if (NetworkingTags.UnitSubjects.UpdateHealth)
    62.                 {
    63.                     //We update our HP here.
    64.                     Health = (float)data;
    65.                 }
    66.             }
    67.         }
    68.     }
    69. }
    70.  
    Edit: Looking at your screenshots, it seems as if you separated the code where you receive from the darkrift API and the object itself. Also taking into account of the unit error you posted, it sounds as if the NetManager is attached to the gameobject, and thus when it destroys itself, you get the error. Also check if you are running the receive script and whether you have attached the function event properly.
     
    Last edited: Dec 31, 2015
    Jamster likes this.
  3. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Hmmmm Interesting, the logs may show some insight into it so that would be good :)

    Also interesting... Both of those should work... Can you tell me what SendReply and SendNetworkMessage are returning? Should be true... :/
     
  4. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    @Jamster Its returning true for both methods.
     
  5. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Ehhhhhh that's not very helpful then :( Definitely calling DarkRiftConnection/API.Receive in Update? :p

    I assume you've tried sticking a debug statement in a receive method to see what tags subjects arrive? Sometimes that's helped me... I could be a DarkRift problem but I'd be very surprised :confused:
     
  6. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Yep I stuck a debug statement in the receive. I had a join message that successfully came through. My client definitely didn't receive the message at all. If my data is not properly serialized, would it cause this type of problem? I'm suspecting its because its not serializing the data properly.


    Code (CSharp):
    1.         [System.Serializable]
    2.         public class PacketUseTypeID
    3.         {
    4.             public PlayerType thePlayerType;
    5.             public ushort client_id;
    6.         }
    7.         [System.Serializable]
    8.         public class PacketPlayerData
    9.         {
    10.             public PacketUseTypeID[] theListOfPlayers;
    11.         }
    12.         [System.Serializable]
    13.         public enum PlayerType
    14.         {
    15.             Red = 0,
    16.             Green,
    17.             Blue,
    18.             Yellow
    19.         }
    20.  
    21.  
    So I create a PacketPlayerData and fill it up and send it. Would there be any problems here?

    Edit: After testing taking away the data part, its still not sending properly.

    Edit 2: I created another script to debug this problem out. I would press C and the unity client send a message to the server to send a message back, using the send reply / send network message method. It didn't work.


    Code (CSharp):
    1.                 else if(msg.subject == NetworkingTags.ServerSubjects.SendMeSomething)
    2.                 {
    3.                     Interface.Log("Sending C");
    4.  
    5.                     DarkRiftServer.GetConnectionServiceByID((ushort)con.id).SendReply(NetworkingTags.Controller, NetworkingTags.ControllerSubjects.SendTest, null);
    6.                 }
    The message clearly goes to the server, but the server can't send back.

    I tried changing the above to
    Code (CSharp):
    1. con.SendReply(NetworkingTags.Controller, NetworkingTags.ControllerSubjects.SendTest, null);
    and it also doesn't work.

    This is really weird, because when I first started using DarkRift it was fine. Just last month I had to rework my backend plugin totally, and now I'm stuck with this problem. Could this also be caused by the new Unity update? I doubt it, but can you check over on your part?
     
    Last edited: Dec 31, 2015
  7. Whippets

    Whippets

    Joined:
    Feb 28, 2013
    Posts:
    1,653
    Hey @Jamster I see the versions on the assetstore are dated August, is development still active, and did you get round to adding RUDP?
     
  8. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Could be, however I'd be very surprised if it was. If an exception occurred on the server side then it should immediately surface, if it occurred client side then I suspect it could be lost in the threading actually. A good thing to try might be to set DarkRiftAPI.workInBackground to false on your client which should cause any hidden errors to appear on DarkRiftAPI.Receive o_O

    The only think there might be that enum... in the end it's a class so it shouldn't be a problem and I'd expect the underlying BinarySerializer to throw an error if it were :confused:

    That may not be a fair test because the BinaryFormatter can't serialize just 'null' so DarkRift handles that separately, therefore you're bypassing some of the code that you would usually use.

    It's unlikely to be Unity but I'd definitely recommend trying the workInbackground = false (if you're on DarkRift 1.3), the multithreaded API was added last update so could very well be part of the problem :confused:

    I seem to be working on a bi-anual update rota so the next update should be January-ish :) RUDP will hopefully be in the complete rewrite update after (summer-ish) :)
     
    Last edited: Jan 1, 2016
    Whippets likes this.
  9. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    @Jamster I've been getting a number of inconsistent results, but you are right in that using null would fail. I've changed null to "" and it worked. So after a load of testing it would seem that yes, its my data that is causing it to fail. When the data I'm sending is "", it would send properly, while sending that PacketPlayerData would fail.

    Edit: I've changed my code so that it won't send the enum anymore. It will now send a List of
    Code (CSharp):
    1.         public class PacketUseTypeID
    2.         {
    3.             public int thePlayerType;
    4.             public ushort client_id;
    5.         }
    However, this still doesn't work. Is there any prerequisites to serializing our own classes?
     
    Last edited: Jan 1, 2016
  10. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Hmmm that is interesting, that suggests the code for sending simply null is broken which I wasn't aware of...

    Nevertheless, did you try setting DarkRiftAPI.workInBackground (or DarkRiftConnection is you're using that) to false? That's still my best guess as to finding out more information.

    The only prerequisites I know of are that both the sender and receiver must have access to exactly the same object (so the same object defined in 2 the server assembly and the client assembly is not compatible) and that (apparently) you can't serialize null. o_O Whereabouts are your objects defined actually?

    DarkRift 2 will have it's own serialization system so most of those limitations should disappear thankfully, as will the huge bandwidth :D
     
  11. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Ok I was wondering why I couldn't find the workinbackground then I realized it was the client. So yes, error messages came out.

    Code (csharp):
    1.  
    2. FileNotFoundException: Could not load file or assembly 'MinersBombMinersServerPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
    3. System.AppDomain.Load (System.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/AppDomain.cs:746)
    4. System.AppDomain.Load (System.String assemblyString) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/AppDomain.cs:728)
    5. (wrapper remoting-invoke-with-check) System.AppDomain:Load (string)
    6. System.Reflection.Assembly.Load (System.String assemblyString) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/Assembly.cs:576)
    7. System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetDeserializationType (Int64 assemblyId, System.String className) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:832)
    8. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadType (System.IO.BinaryReader reader, TypeTag code) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:874)
    9. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadTypeMetadata (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:629)
    10. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectInstance (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:269)
    11. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:191)
    12. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:223)
    13. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (BinaryElement element, System.IO.BinaryReader reader) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:130)
    14. System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:104)
    15. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179)
    16. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)
    17. DarkRift.Transmission.TransmissionProtocol.DecodeMessageData (DarkRift.Transmission.DataBufferItem item)
    18. DarkRift.Transmission.TransmissionProtocol.DecodeMessage (DarkRift.Transmission.DataBufferItem item)
    19.  
    edit: I'm guessing that I need to link the plugin to the unity client? I'm guessing that I need the assembly of the class in the Unity Client since it needs to unserialize the data, which is located in my plugin.
     
    Last edited: Jan 1, 2016
  12. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Ahhhh lovely :D

    Yeah, the objects you are serialising unfortunately need to be exactly the same, I find it's quite helpful to put them in a separate dll which both the server and client can reference so that you're not distributing your plugin with your game :) Alternatively you could manually serialise everything for better performance and bandwidth use as well :)
     
  13. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Does this mean that the plugin dll needs to be compiled in .net 2.0? I'm running low on time, so thats why I'm not doing manual serialization yet.

    Oh it needs to be 3.5 for .Net. Got it working now! Honestly still kinda confused about how Unity can ready 3.5, but is only on 2.0.
     
    Last edited: Jan 2, 2016
  14. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Good good :) Unity's .NET version is usually best not to think about too hard ;) It's a sort of mix :p
     
  15. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Question: When I disconnect a client from my server side, in the client does DarkRiftAPI.isConnected updated to reflect this? What is happening is that I disconnect a client from the server side in ConnectionService.onPlayerConnect, but the client still thinks its connected. The client knows that the existing connection was forcibly closed (as logged by the error), but doesn't update isConnected to reflect this. Do I update isConnected myself? How do I check if my client is connected (with the exception of writing try / throw codes in all the networking codes).

    I'm using con.close(). Is this the right way? When I check, it seems that even if I close the connection on the server using con.close(), the connection still exists. If I close the connection by closing the client, the connection closes properly and does not display anymore.

    Also, there are times when I have to manually click on the server, and then press some button in order for it to continue running. This usually happens when I disconnect clients. Since I have logged the disconnects, sometimes they only appear after the I press a button on the server. This usually coincides with when the server starts giving the connection limit error. It happens like this. 1: I disconnect all clients. 2: "Shake" the server up to make it respond. 3: connect two clients. Only one out of the two succeeds, with the other being rejected due to the limit. No error messages pops up on either connection.
     
    Last edited: Jan 5, 2016
  16. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    You are quite right in how you're doing it actually. It's a server bug, the server never sends the disconnect message when you call Close()... That'll be fixed next version (when I get round to submitting it!) :)

    As for having to click on the server, are you sure that you have Unity set to Run in the background (assuming you're using the embedded server)? That might be a cause of it because I think DarkRift would still process messages but your plugin code wouldn't update if Unity is paused.

    ADDED: As a workaround for the disconnect glitch add this line to the onPlayerDisconnected handler:
    Code (csharp):
    1. con.SendNetworkMessage(new NetworkMessage(0, DistributionType.Reply, 0, 255, 0, 0));
    EDIT: That actually don't seem to help... Which is worrying... I'll look again later...
     
    Last edited: Jan 6, 2016
  17. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Thanks for the update! Will the next version release soon? If not, I'll just make a workaround.
     
  18. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    I'm bogged down with work at the moment, I'll submit it when I can get around to it and I've fixed those bugs... Late January?
     
  19. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Could you include the documentation for Network Messages in the next release? I can't find them. It took me too long to realize that if I wanted to get data from the server side, I had to use networkmessage.decode().
     
  20. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Sure thing, I'll try and make it clearer :) is it not in the server reference?
     
  21. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Not in mine at least. And not on the one on the support website:)
     
  22. Gaios

    Gaios

    Joined:
    Nov 26, 2012
    Posts:
    10
    I have been playing around with DarkRift over the last couple of days and I wanted to leave a bit of feedback:

    I am deeply impressed. I have tried Photon, Forge Networking and TNet and even though those are good too, they were not well suited for my type of project. I am working on a turnbased collectible card game where all game logic on the clients is calculated by a standalone authoritative server (no physics). All other solutions forced me to work around their "features", but the plugin architecture in DarkRift does not have this problem and makes it really easy to extend functionality. You can either use an existing plugin or just develop your own.

    I feel this product should be a lot more popular than it is and I believe it could be a real competitor. If you were to play your cards right, you could make a lot of money from this and you might even be able to put your indie studio on the map. My main issue is this:

    Two updates a year are a real turnoff. If I want to use this in a commercial product, I can not afford to potentially wait half a year for bugfixes and with the product being closed-source it is a risk for any company. You should consider rethinking the closed-source approach and maybe make an open source version available to owners of the Extreme Edition.

    I will give this another week or so to see if I am still as amazed as I am right now. If so, you have another customer for the Extreme Edition and I will take the time to rip the current solution out of my game and replace it with yours before it hits Steam later this year.

    1. I had to google this support thread, because I could not find it on the store page or on your homepage. If customers or potential customers need help or have questions, they need to be able to ask them without much effort. Try to keep the entry barrier low (maybe it is there and I was too stupid to see it). Maybe change the link to "Support Website" to this thread.

    2. The Name DarkRift by itself is bad from a marketing and SEO perspective. Even though my google search is trained for unity-related requests, there were way too many results for the N64 game in the mix. I also can not infer from the title what this product is supposed to do. If you want to understandably stick with DarkRift, maybe add the word "Networking" to it. Helping people to see your product and its purpose is very important. You are on the store for one and a half years now and I only just found out about DarkRift even though I do use the Asset Store on a regular basis.

    3. The initial price of 650$ for the Extreme Version was in my opinion a blunder. Most indies and hobby developers would not consider coughing up so much money for a networking solution that is rather unknown. Bringing the price more in line with your competitors was a very good decision. Having more customers does mean you need to spend more time on support, but popularity is never a bad thing.

    4. The homepage and the product logo have an amateurish quality about them. The first goal of good sales is to convey trust and trust comes, among other things, from presenting a professional exterior. I checked out the product homepage and since you were running on a subdomain I also looked at your games. Don't be offended, but what I saw there, made me almost not try out DarkRift. If you want to get serious about it, maybe get it its own domain with a simple clean template.
     
  23. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Hey Giaos,

    I appreciate the advice, I'm no businessman and so any advice in that area is helpful :) I'm glad you like DarkRift Networking though!

    DarkRift is unfortunately still something I just do in my spare time. I'd hoped it would grow a bit and that there'd be more of a community to help with stuff like support but it never really did that much; in terms of writing it, it's still just me doing it and so I'd love to be able to make more releases but I simply don't have the time to :(

    I've started rewriting DarkRift for the summer, and with that I want to try and get some other people involved in the maintaining of DarkRift and actually implement a lot of your proposals. I'm hoping that I can make it fully open source and then provide a service/pro version on top of that but really that's to be decided later, I'd love to do it but with the current version of DarkRift it's not too easy (i.e. if I made it open source you'd be able to unlock unlimited users by simply changing a constant :p ).

    The rewritten version is actually fairly majorly different, not in terms of operation and principle but rather the API and underlying code. There are some limitations I didn't foresee when I wrote it and they're coming back to haunt me now so it needs a complete refresh. I know that's a severe disadvantage for any user but changing it will mean it fits in with .NET conventions, will allow it to be cross platform (i.e. not just for Unity if I wanted), make it nicer to maintain (Some of the internals really need ripping out and replacing), plus a hell of a lot more...

    The domain was supposed to be temporary, DarkRift actually has nothing to do with NinjaPoke Studios, the domain was just a useful place to put the website and I never got round to changing it.

    I'd love to be able to put more into DarkRift and I hope if I can get others onboard with DarkRift 2, then it'll be much bigger, more active and will get a lot more love in general.

    Jamie (the one lonely guy on DarkRift!)
     
  24. Gaios

    Gaios

    Joined:
    Nov 26, 2012
    Posts:
    10
    Thanks for the feedback. I hope DarkRift gets a little more traction. Maybe even enough to let you do this fulltime. :)

    Too bad networking is my weak spot as a software developer. Otherwise I would have been happy to help you out.
     
    Jamster likes this.
  25. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    DarkRift 1.4 has been sent to the Asset Store!
    It usually now takes 1-2 weeks for it to get accepted but nevertheless it's sent! :p
     
  26. Gaios

    Gaios

    Joined:
    Nov 26, 2012
    Posts:
    10
    Alright, I'm in. :) Just upgraded to the Extreme Version.

    Any chance of you posting the change log for 1.4 in here, so we can see it before it goes live?
     
  27. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Thank you very much :) Certainly:
    Server:
    - Made server use async sockets to improve performance.
    - Made PerformanceMonitor.totalConnectionReadCounts obsolete (use totalConnectionHeaderCounts and totalConnectionBodyCounts instead).
    - Added PerformanceMonitor.totalConnectionHeaderCounts, totalConnectionBodyCounts, totalConnectionHeaderTime and totalConnectionBodyTime.
    - Fixed off by 1 glitch in the connection limit.
    - Fixed informing client of closing/kicking.
    - Stopped TCP grouping messages.
    - Fixed kickall and kick command bugs.

    API:
    - Added ConnectInBackground methods.
    - Fixed informing server of disconnects.
    - Stopped TCP grouping messages.

    In other news the current build of DarkRift 2 received it's very first TCP packet! :D UDP is however... broken :(
     
  28. Gaios

    Gaios

    Joined:
    Nov 26, 2012
    Posts:
    10
    Thank you. That was fast. Looking forward to your progress on V2.
     
  29. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    I happened to be browsing the forums at the time :p
     
  30. GuilhermeStrice

    GuilhermeStrice

    Joined:
    Dec 8, 2015
    Posts:
    23
    Can i help with DarkRift V2 ? ive been doing C# for 2 years i think i can help
     
  31. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    PMed you :)
     
  32. GuilhermeStrice

    GuilhermeStrice

    Joined:
    Dec 8, 2015
    Posts:
    23
  33. GuilhermeStrice

    GuilhermeStrice

    Joined:
    Dec 8, 2015
    Posts:
    23
  34. TheWyrdsmith

    TheWyrdsmith

    Joined:
    Aug 14, 2013
    Posts:
    2
    Hi,

    Really impressed so far with how easy it is to get things running! As promised it took less than 20 minutes to get the plugin tutorial working :)

    One thing I am having a bit of trouble with; the Plugin base class and the DarkRift.xml files seem to indicate that there is a repetitive timed Update functionality. However, visual studio can't find the corresponding call in the dll and I can't find any documentation on what or where to add a time period to the config files.

    Is this a WIP feature? If I need to run a fake client and send messages that tell my plugin to update that's not an issue, but some clarification on expected usage would be great. Thanks in advance!
     
  35. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Hey! Glad you like it! (And welcome to the forums!)

    To get calls to Update you need to add
    Code (csharp):
    1. public override void Update()
    2. {
    3. //Your code
    4. }
    to your plugin and it'll get called every 10 milliseconds (I removed the user set rate and forgot to change the docs!). If you need to be able to set the rate then look at the System.Timers.Timer class in .NET and you can create your own timer for it (that's all Update is underneath).

    Jamie
     
  36. TheWyrdsmith

    TheWyrdsmith

    Joined:
    Aug 14, 2013
    Posts:
    2
    reese01 likes this.
  37. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Oh... Thanks for that :) I guess it will just usually execute every 15 ms instead then :p

    It's really just a quick add-on for people to get repeated updates if they need, if you were to do anything precise then I'd recommend using a high resolution timer instead definitely :)

    Thanks for the links!
     
    reese01 likes this.
  38. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
  39. Hunkofsteel

    Hunkofsteel

    Joined:
    May 13, 2015
    Posts:
    20
    Hey keep up the good work on Dark Rift! Yesterday I updated my DarkRift to the current version, along with my server and what not. I'm encountering some problems.... specifically, closing the connection.

    Before the update, I was closing the connection from the client side. Meaning that I would send a message over to the client side from the server and the client would close most of the time. It would seem that after the update, closing the connection from the client would result in a

    System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
    at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
    at DarkRift.ConnectionService.ReadHeaderCallback(IAsyncResult result)
    at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Net.ContextAwareResult.Complete(IntPtr userToken)
    at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
    at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

    and crash the server. Makes sense, I guess since I am forcibly closing the connection on the client side.

    Because the sending the disconnect message to the client was made as a workaround to the original "I can't shut connection in server " problem I had, I changed the code so that it would just shut the connection on ConnectionService.onPlayerConnect .

    While this didn't crash the server, it caused the server to belch errors.
    21/1/2016 00:38:47 AM [Trace] #### Server boot ####
    21/1/2016 00:38:47 AM [Trace] #### Server boot ####
    21/1/2016 00:38:47 AM [Log] Server mounted, listening on port 4296
    21/1/2016 00:38:47 AM [Trace] Found plugin: C:\Users\Roland\Documents\Git\miners-bomb-miners\DarkRiftServer - Free\Plugins\MinersBombMinersServerPlugin.dll, type of MinersBombMinersServerPlugin.MinersBombMinersServerPlugin
    21/1/2016 00:38:47 AM [Trace] Found a total of 1 plugins.
    21/1/2016 00:38:47 AM [Log] ------------------------------------------
    21/1/2016 00:38:47 AM [Log] IPADDRESS FOR THIS SERVER IS: 192.168.0.103
    21/1/2016 00:38:47 AM [Log] Please connect to the IP Address
    21/1/2016 00:38:47 AM [Log] ------------------------------------------
    21/1/2016 00:38:47 AM [Log] Loaded plugin: Miners Bomb Miners Plugin Version: 1.1
    21/1/2016 00:38:54 AM [Log] Connected: 127.0.0.1:57979
    21/1/2016 00:38:54 AM [Log] sending money : 500
    21/1/2016 00:39:04 AM [Log] Connected: 127.0.0.1:57984
    21/1/2016 00:39:04 AM [Log] sending money : 500
    21/1/2016 00:39:10 AM [Log] Connected: 127.0.0.1:57989
    21/1/2016 00:39:10 AM [Log] Closing conenction
    21/1/2016 00:39:10 AM [Log] Disconnected: 127.0.0.1:57989
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.
    21/1/2016 00:39:10 AM [Error] Network stream to client has been disposed! Trying to recover by saftely closing the connection on the server.

    This goes all the way till I shut down all connections to the server. As you can notice in the log above, I connected two clients to the server, and tried to disconnect the third one. What am I doing wrong that could cause this?
     
  40. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Hmmm...

    How are you closing it? The former bug was fixed as far as I knew so you should be able to just safely close the connection using ConnectionService.Close() on the server; no need to send anything yourself anymore. o_O
     
  41. KHRZ

    KHRZ

    Joined:
    Mar 2, 2013
    Posts:
    54
    I'm having an issue which I'm wondering if DarkRift (v1.3 free) have a problem. I have some code run by ConnectionService.onData where the execution is delayed, until some unrelated player disconnects from the server. It happens when I have around 5 players connected (but in individual games, they are not interferring which each others). I made it print a stack trace, and it seems to me that the ThreadPoolWorkQueue is ignoring a thread until some condition, which is triggered when some player disconnected (note: a specific player, not any one)
    Note: HandleonData is the function run by onData.

    Stack trace:
    at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
    at System.Environment.get_StackTrace()
    at DwarfHeim.Room.Start()
    at DwarfHeim.Room.FinishedLoading(Player plyr)
    at DwarfHeim.DwarfheimPlugin.HandleonData(ConnectionService con, NetworkMessage& data)
    at DarkRift.ConnectionService.ProcessDataItem(Object context)
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
    at System.Threading.ThreadPoolWorkQueue.Dispatch()
     
  42. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    Just Bought The Pro Version, I like you are doing, but I think the Documentation need lots of improvements (Pls not more PDF, just http://stackoverflow.com/questions/641364/c-sharp-documentation-generator).

    Also there are a lot of things difficult to understand or missing :
    - Connect() Timeout ?.
    - NetworkMessage ? there is no documentation at all, but it is used in one example, about serialization is not documented, there is examples, but its not all clear.

    Well you are doing an amazin job, I bought pro when you announced the DarkRift 2, maybe all the documentation will change so there is no point to spent time on it right now, so I will wait for the New version, but I think it is the weakest part of the project, Im sure I will purchase the Extreme version if the documentation and the project keep improving.
     
  43. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Hey! Thanks for the feedback :)

    That's definitely a good suggestion actually, most of the docs are already implemented in XML docs (well, the Desc part is but the rest can be added I'm sure) so that would make life easier :p Not entirely sure why I never did that in the first place to be honest!

    I'll add a timeout to Connect when I next update (or at least in DarkRift 2) and I'll add documentation for NetworkMessage :)

    Thank you, I'm glad you like it and feedback's always good :)

    Jamie

    ADDED: For DarkRift 2 I was thinking about having the reference docs as you suggest and then hosting a wiki for the rest of the docs, that way people can always edit them if they feel like things need improving or if they want to add to it etc. Obviously I'd still update them for each version but does that seem like a good idea in general? :)
     
    Last edited: Jan 23, 2016
  44. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    I'm not sure I fully understand the circumstance that this occurs in, am I right in thinking one of the onData events isn't being fired until a player disconnects? Is it happening everytime or randomly once 5 players are on? I take it the server's standalone?

    Seems very unlikely to be a ThreadPool glitch so more likely to be DarkRift :(
     
  45. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    Ofc it will be very Wellcome, but if you just generate the html and put it in the Asset Store package it will be enough.

    I was playing with DarkRift this WeekEnd, and at the end I realize that I cannot build my entire game with DarkRift, at least I would need V2 to acomplish my goals.

    But Im thinking to use it with Unet, and maybe one day I can switch to use it entire.

    For me right Now, more important parts are UDP, timeouts, the new Thread Dispatcher System, and multiply Rooms/Channels.

    But I will use it to communicate between server and clients, in other ways.
     
  46. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    By the Way, One improvement for the Server.cs

    Code (CSharp):
    1.     void ProcessAllQueueItems()
    2.     {
    3.         //Empty the queue of items
    4.         int QueueCount;
    5.         lock (updateQueue)
    6.         {
    7.             QueueCount = updateQueue.Count;
    8.         }
    9.         while (QueueCount  > 0)
    10.         {
    11.             QueueItem item;
    12.  
    13.             lock (updateQueue)
    14.             {
    15.                 item = updateQueue.Dequeue();
    16.                 QueueCount = updateQueue.Count;
    17.             }
    18.  
    19.             item.processingMethod.Invoke();
    20.  
    21.             if (item.reset != null)
    22.             {
    23.                 item.reset.Set();
    24.             }
    25.         }
    26.     }
     
  47. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    I'm sorry to hear that, I do hope that you can return to DarkRift in the future though. And thank you for the improvement, I'll add that now :)

    Thank you for all you comments and suggestions and I hope your game goes well :)
     
  48. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    I've posted a few updates to the DarkRift 2 WIP thread if anyone's interested :) I've had a few people ask me about progress so I'll throw the link out there again :)
     
  49. Dark_Tiger

    Dark_Tiger

    Joined:
    Oct 21, 2014
    Posts:
    32
    Just a few questions, if I were to write plugins for the free version for prototyping and then eventually get around to purchasing the extreme version, is the API all the same? So will I just be able to chuck the plugins into the extreme version, boot up the server and have everything work. Also would you be able to give an estimation for how long you think it'll take you develop DarkRift 2, I'm guessing it'd at least be a few months and some.
     
  50. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    830
    Yup! There's absolutely no differences in the API :) The only thing that changes is actually an internal constant stopping you having more than 20 players :p

    I'm aiming for the summer (July ish?), I don't know yet how realistic that is because I don't have much idea how busy I'll be :)