Search Unity

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:
    1,102
    Not had much time to look I'm afraid!
     
  2. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    Any chance of an update on this? It's a pretty important issue for my game.
     
  3. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    I think I've found the problem, there's a blocking call on send instead of an asynchronous call. I'll remove and that should see a performance increase as well :)

    Jamie
     
  4. Lisk

    Lisk

    Joined:
    Oct 23, 2013
    Posts:
    99
    Oh that's very good news!
     
  5. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Version 1.4.6 has been released on the asset store!

    This fixes the above issue that meant lagging players caused the entire server to lag and should improve performance as well :)
     
    tequyla and Lisk like this.
  6. Kalle801

    Kalle801

    Joined:
    Mar 3, 2013
    Posts:
    80
    Hello dear Dark Rifter. I Need some help cause im completelly new to Coding.
    Could someone post the Code for the "Standard TP and OR FP Character" of unity Standard Assets please?
    I try to get this working but im not able to Code like this.

    This would be very helpfull.

    best Regards and Thanks in Advance.
     
  7. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    I'm afraid I don't have them to hand, I suggest you post in the scripting forum instead as you'll probably get a faster answer!

    I have a feeling the standard assets might have moved to the asset store so maybe check there as well!
     
  8. Basilios03

    Basilios03

    Joined:
    Feb 3, 2014
    Posts:
    2
    Hi, I followed the embedded server you provided with the package to make my own authoritative server project, all was well until I used OnPostPlayerConnect to spawn player. I had to add player spawning to the Enqueue function in the Server class. Since the Action delegate that Enqueue takes doesn't expect any parameters, I had to work around it in a kind-of-hacky way. Am I missing something or should I edit Server.cs to add new delegates?
    Edit: I'm getting a "NotConnectedException" after adding to the queue. Are we not supposed to add events manually?
     
    Last edited: Oct 21, 2017
  9. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    You shouldn't really need to edit the Server.cs file (only in extreme cases), you should just be able to subscribe to the event as normal and spawn the player as you would in the standalone server.

    Can you share more details? :)
     
  10. Basilios03

    Basilios03

    Joined:
    Feb 3, 2014
    Posts:
    2
    Sorry I should've mentioned that it was a threading problem. My guess was that OnPostPlayerConnect is not being handled correctly by Server.cs, or not at all. So I added the spawning function to an event and sent it to the Enqueue function in Server.cs. It's easier to just show you the script :)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using DarkRift;
    5. using System;
    6.  
    7. public class ServerManager : MonoBehaviour {
    8.     Server server;
    9.     event Action spawnPlayer;
    10.     ConnectionService spawnCon;
    11.  
    12.     private void Awake()
    13.     {
    14.         server = GetComponent<Server>();
    15.     }
    16.  
    17.     void Start()
    18.     {
    19.         spawnPlayer += SpawnPlayer;
    20.         ConnectionService.onData += OnData;
    21.         ConnectionService.onPostPlayerConnect += OnPostPlayerConnect;
    22.     }
    23.  
    24.     private void OnPostPlayerConnect(ConnectionService con)
    25.     {
    26.         Debug.Log("Server: player connected");
    27.         spawnCon = con;
    28.         server.Enqueue(spawnPlayer);
    29.     }
    30.  
    31.     public void SpawnPlayer()
    32.     {
    33.         //Spawn server player.
    34.         ServerPlayer sPlayer = ServerPlayersManager.instance.SpawnPlayer(spawnCon.id);
    35.     }
    36.  
    37.     void OnData(ConnectionService con, ref NetworkMessage data)
    38.     {
    39.     }
    40. }
    41.  
    Initializing directly from OnPostPlayerConnect throws "INTERNAL_CALL_Internal_InstantiateSingle can only be called from the main thread."

    As for the "NotConnectedException", turns out it's because I was sending messages via DarkRiftAPI from the server scene. I'm still trying to find my way around who does what.
     
  11. BadUncleGames

    BadUncleGames

    Joined:
    Aug 10, 2015
    Posts:
    39
    Ho folks,
    This may be a simple question and due to me just getting used to how Darkrift is working but here goes.
    1. I have a dedicated server and three scenes - a login, a character build then a main scene. In standalone this is working fine (it logins via mysql then you can build your UMA and get into the main scene - based on the Yasil.de tutorials)
    2. I have some need of physics and eventually navmesh and from what I read I need to use an embedded server for this

    So my question is, what's the approach for the client changing from login to build to my start scene? Do I put a separate server.cs in an empty unity scene to manage each of three scenes/servers or do i run the start scene in which case how do i use the login and mysql plugins etc.? I'm not clear on the process for this.
    As it will be an mmo style there will be other scenes that characters will eventually switch between etc.

    Any pointers would be appreciated.

    [Edit] - My thoughts about the best way to run this (and happy to be pointed in a better Darkrift direction) is that my login/mysql plugins and scenes could connect to my standalone console server then once authenticated i connect to my embedded server (one per scene or zone) .....with just the Mysql plugin for DB updates (connected to the same DB as the login). Is that a feasible scenario or is there a more efficient way to handle the login/charbuild and then physics embedded scenes?
     
    Last edited: Oct 24, 2017
  12. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    @Basilios03 Yep that's a bug, it's not routed through Server.cs so that'll be fixed soonish :)
    For now you can probably do something similar to this
    Code (csharp):
    1. EnqueueWaitHandle(() => YourOnConnectRoutine).WaitOne();
    which will queue and pause the event until it's executed on the main thread.

    @BadUncleGames You're on the right lines. From what you've said I would probably do this:
    1. Authenticate with a web server over HTTPS and have the webserver store an auth token for the user.
    2. Client connects to the DarkRift embedded server and passes it the token.
    3. DarkRift server checks the token with the database.
    4. Client loads build scene and builds character...
     
  13. Jackk_

    Jackk_

    Joined:
    May 2, 2017
    Posts:
    49
    Hey Jamster, Just want to say I am a massive fan of your work, but I do have an issue that I cannot for the life of me work out how to fix.

    The Problem: The Information sent from my game, isn't getting saved to my MySQL Database.

    Background Information: I have been following Yalis' tutorial on making a MMO in the Unity Engine, and have done everything he has in terms of the coding and database is concerned but for some reason when I send data using DarkRift, It doesn't get stored in the database.

    Stuff Relating to the DarkRift side of things

    I have a network manager assigned to an empty asset on my Unity Game, which determines the port etc: https://gyazo.com/282e0b742fa78fd8d56507d3f23dc2dc
    • This file could be the cause of the problem as the port of my game is 4296 but the port of the MySQL database is 3306
    • This file could also be the cause of the problem as my server is hosted locally but the string IP is "127.0.0.1" so I'm not sure if that should be changed to localhost
    I have Y-Const File: https://gyazo.com/389ddd696bd9375e439c7e7a237ff0c5

    I have a simple Login File: https://gyazo.com/34bafa334cc36a8ed72cc10017955f53

    I have a login manager File: https://gyazo.com/6ce516ff15917b4b2c796a295caceaed
    • The login manager file could also be the cause of the problem as it says SendToServer(Yasil.NT.LoginT, Yasil.NT.LoginS.loginUser, writer) because Yasil was the name that the tutorial used, I'm not sure if it needs to be something different.
    I also have a LoginButton, which basically sends all the information to the database when the login button is pressed on the UI of my Unity Game: https://gyazo.com/39374a5ce0972d1b49ef2643b0650a62

    I also have a MySQL Connector .dll which looks like this: https://gyazo.com/73bd587fcc2a00f80f3860b61faa1335
    *there is more to this image but it seemed irrelevant

    The reason this problem is so hard for me to fix is because when I launch the DarkRift server.exe and Press on the Login button and Add user button, everything on the console seems fine as there are no errors but for some reason the data isn't being sent to my database. Evidence: https://gyazo.com/0000169b652839d3c1000b5499364f76

    Stuff Relating to the SQL Database

    Using MySQL Workbench to make the database

    Database Tables: https://gyazo.com/ff288887c82675315d3320bb7c6c0b2b
    Database Server Status: https://gyazo.com/14ee6c12b9e0f0e1f514b298439b3e5f
    Settings.cnf (The file that knows what my database account is so it can input data using it): https://gyazo.com/c08f5da38a393e5e16ac0f8a80630f9a

    I'm not sure if there are any extra steps that I missed when making my database, so feel free to ask me questions on my setup etc.

    And yes my account is username, password but the account has every possible privilege to all schemas so I really don't understand what is going wrong, if you could please help me solve this problem, I would greatly appreciate it :)
     
  14. Jackk_

    Jackk_

    Joined:
    May 2, 2017
    Posts:
    49
    Issue Resolved
     
    Jamster likes this.
  15. rifttime

    rifttime

    Joined:
    Jun 3, 2017
    Posts:
    2
    Hi,
    i'm trying to test DarkRift but cant figure out.
    I run server on PC, run scene in editor and i get conencted.
    But it don't connect from other PC or Android.
    Unfortunately, i didn't found any instructions for that.
    Can you please help me?
    Thx.
     
  16. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    @Jackk_ Glad you figured out your issue!

    @rifttime Are you running the other PC/android on the same network or are you running from a different network? If the latter, have you port forwarded your router?
     
  17. rifttime

    rifttime

    Joined:
    Jun 3, 2017
    Posts:
    2
    @Jamster i'm running on the same network.
    I didn't change port.
     
  18. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Hmm... In the case make sure your firewalls are set to give DarkRift access and you can try connecting using Telnet instead to verify if you can connect using a simple example.
     
  19. Nivbot

    Nivbot

    Joined:
    Mar 21, 2015
    Posts:
    65
    Ugh, I am losing my mind trying to figure this out. Aaaaall day looking it up to no avail no matter which networking solution I look at. Darkrift looks really good and I want to use it but I want to start from where I will eventually end up. That might not make sense right now but hear me out.

    I want to work on learning it as I go but I want to start out using my remote machine as other players would remotely. I don’t want to do it from the same machine.

    I already have an apache server hooked up at my home that I can access remotely. How in god’s name do I do this with Darkrift? For instance, how do I put darkrift on a machine with the unity project and say as an example the ip address is 23.123.1.12 to access from outside. How do I set this up? That’s how I want to learn because that’s how I’m going to use it eventually.

    In short, how does ones set up Darkrift to allow for remote connections? Everything just shows using both server and client on one machine. I don’t want that.
     
  20. Nivbot

    Nivbot

    Joined:
    Mar 21, 2015
    Posts:
    65
    Do I just put it on the machine I want use as the server and port forward on its private ip address the set up to use the network’s ip to that machine port from somewhere in the Darkrift server?

    I hope I don’t sound like a complete idiot I’m just not well versed on setting this sort of thing up
     
  21. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Sounds about right:
    1. Put DarkRift on the server
    2. Port forward your router so port 4296 (unless you change it) directs to port 4296 on your server
    3. Add firewall exceptions if you have one
     
  22. Nivbot

    Nivbot

    Joined:
    Mar 21, 2015
    Posts:
    65
    Just wanted to say thanks. I put the server on my laptop (which will obviously not be used as a real server) and just set port forwarding on 4296 on that machine, changed the example project to connect to my public ip, compiled and ran it on that machine, ran the project from my main computer and voila. It worked.

    Now the real challenge begins
     
    Jamster likes this.
  23. Gemberkoekje

    Gemberkoekje

    Joined:
    Mar 12, 2013
    Posts:
    2
    Hi. Can I use darkrift in a console-only application? I've been trying something like below, but the ports don't seem to be listened to. I'm probably missing something (maybe even something obvious) or it's simply not supposed to work this way, but in any case, any reply would be appreciated.

    using DarkRift;

    Code (CSharp):
    1. namespace StreamerServer
    2. {
    3.     class Program
    4.     {
    5.  
    6.         static Vector3Carrier[] cubes;
    7.  
    8.         static void Main(string[] args)
    9.         {
    10.             ConnectionService.onData += OnData;
    11.             var exit = false;
    12.             while (!exit)
    13.             {
    14.                 foreach (ConnectionService cs in DarkRiftServer.GetAllConnections())
    15.                 {
    16.                     for (int i = 0; i < cubes.Length; i++)
    17.                     {
    18.                         cs.SendReply(0, (ushort) i, (Vector3Carrier) cubes[I]);
    19.                     }
    20.                 }
    21.             }
    22.         }
    23.  
    24.         static void OnData(ConnectionService con, ref NetworkMessage data)
    25.         {
    26.             //Decode the data so it is readable
    27.             data.DecodeData();
    28.  
    29.             //Convert the data to Vector3
    30.             var pos = (Vector3Carrier)data.data;
    31.             ushort id = data.subject;
    32.  
    33.             //Move the cube
    34.             cubes[id] = pos;
    35.         }
    36.     }
    37. }
    [/I]
     
    Last edited: Nov 28, 2017
  24. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Yeah, you can! :)

    Have a look at the Server.cs file in Unity as it'll give you some hints as to what you need to do to start the server (DarkRiftServer.Bootstrap)! You won't need any of the IManualDataProcessor stuff though as that all for joining threads.

    Obviously plugins are the best way to go but if you can't then you can definitely still use DarkRift.
     
  25. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    Hello,wo first use the DarkRift, now i have a problem:
    I add a variable for User's name. and same to the postion and Rotation.

    Now, the new player start game synchronized the postion and Rotation,but Username not,Why?
    (only the first time Username not synchronized, when modified it's synchronized)


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using DarkRift;
    5. using CreativeSpore.RpgMapEditor;
    6. using UnityEngine.UI;
    7.  
    8. public class NetworkPlayer : MonoBehaviour
    9. {
    10.     //The ID of the client that owns this player (so we can check if it's us updating)
    11.     public ushort networkID;
    12.     public string userName;
    13.  
    14.     Vector3 lastPosition;
    15.     Quaternion lastRotation;
    16.     public Vector2 temp_dir;
    17.  
    18.     public Text UIname;
    19.  
    20.     void Start()
    21.     {
    22.         //Tell the network to pass data to our RecieveData function so we can process it.
    23.         DarkRiftAPI.onDataDetailed += ReceiveData;
    24.  
    25.         //Also, make sure we're told if a player disconnects.
    26.         DarkRiftAPI.onPlayerDisconnected += PlayerDisconnected;
    27.  
    28.         //
    29.         DarkRiftAPI.SendMessageToOthers(TagIndex.PlayerUpdate, TagIndex.PlayerUpdateSubjects.Username, userName);
    30.     }
    31.  
    32.     void OnDestroy()
    33.     {
    34.         //When we're destroyed we need to clean up our references
    35.         DarkRiftAPI.onDataDetailed -= ReceiveData;
    36.         DarkRiftAPI.onPlayerDisconnected -= PlayerDisconnected;
    37.     }
    38.  
    39.     void Update()
    40.     {
    41.  
    42.  
    43.         //Only send data if we're connected and we own this player
    44.         if ( DarkRiftAPI.isConnected && DarkRiftAPI.id == networkID ){
    45.             //We're going to use a tag of 1 for movement messages
    46.             //If we're conencted and have moved send our position with subject 0.
    47.             if (transform.position != lastPosition)
    48.             {
    49.                 DarkRiftAPI.SendMessageToOthers(TagIndex.PlayerUpdate, TagIndex.PlayerUpdateSubjects.Position, transform.position);
    50.             }
    51.             //Then send our rotation with subject 1 if we've rotated.
    52.             if (transform.rotation != lastRotation)
    53.             {
    54.                 DarkRiftAPI.SendMessageToOthers(TagIndex.PlayerUpdate, TagIndex.PlayerUpdateSubjects.Rotation, transform.rotation);
    55.             }
    56.  
    57.             //if(temp_dir!= GetComponent<DirectionalAnimation>().GetAnimDirection())
    58.             //DarkRiftAPI.SendMessageToOthers(TagIndex.PlayerUpdate, TagIndex.PlayerUpdateSubjects.Dir, GetComponent<DirectionalAnimation>().GetAnimDirection());
    59.  
    60.             if (UIname.text != userName)
    61.             {
    62.                 DarkRiftAPI.SendMessageToOthers(TagIndex.PlayerUpdate, TagIndex.PlayerUpdateSubjects.Username, userName);
    63.             }
    64.  
    65.             //Update stuff
    66.             lastPosition = transform.position;
    67.             lastRotation = transform.rotation;
    68.             UIname.text = userName;
    69.  
    70.         }
    71.      
    72.     }
    73.  
    74.     void ReceiveData(ushort senderID, byte tag, ushort subject, object data)
    75.     {
    76.         //Right then. When data is received it will be passed here,
    77.         //we then need to process it if it's got a tag of 1 or 2
    78.         //(the tags for position and rotation), check it's for us
    79.         //and update ourself.
    80.  
    81.         //The catch is we need to do this quite quickly because data
    82.         //is going to be comming in thick and fast and it'll create
    83.         //lag if we spend time here.
    84.  
    85.         //If the data is about us, process it.
    86.         if( senderID == networkID ){
    87.  
    88.             //If it has a PlayerUpdate tag then...
    89.             if( tag == TagIndex.PlayerUpdate ){
    90.  
    91.                 //...update our position
    92.                 if( subject == TagIndex.PlayerUpdateSubjects.Position ){
    93.                     transform.position = (Vector3)data;
    94.                 }
    95.  
    96.                 //...update our rotation
    97.                 if( subject == TagIndex.PlayerUpdateSubjects.Rotation ){
    98.                     transform.rotation = (Quaternion)data;
    99.                
    100.  
    101.                 //...update our rotation
    102.                 if( subject == TagIndex.PlayerUpdateSubjects.Dir )
    103.  
    104.                    GetComponent<DirectionalAnimation>().SetAnimDirection((Vector2)data);
    105.  
    106.                 }
    107.  
    108.                 if (subject == TagIndex.PlayerUpdateSubjects.Username)
    109.                 {
    110.                     userName = (string)data;
    111.                     UIname.text = (string)data;
    112.                 }
    113.  
    114.             }
    115.         }
    116.     }
    117.  
    118.     void PlayerDisconnected(ushort ID)
    119.     {
    120.         // This will be called when a player disconnects, if it's the client we represent
    121.         // we need to get rid of this object.
    122.  
    123.         if( ID == networkID ){
    124.             Destroy(gameObject);
    125.         }
    126.     }
    127. }
    128.  



     
    Last edited: Dec 1, 2017
  26. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    How to add a new player at the beginning, other players send information to him?
     
  27. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    If you want data to be synchronised when the player is spawned you will have to add it into the spawn/join messages in NetworkManager as these send the initial position.

    It would also be a sensible idea to move the spawn code to a plugin rather than using a passive server to stop cheating occurring in your game.

    Jamie
     
  28. Slaghton

    Slaghton

    Joined:
    Sep 9, 2013
    Posts:
    139
    Is there anyone else that had this issue? When I got to the #1.4 Unity 5 Tutorial MMO UI and send Login Data part of the tutorial I get stuck. I created the NetworkManager.cs script and placed it in with 127.0.0.1 being the ip and 3306 for port and I get "
    VersionException: Exception of type 'DarkRift.Transmission.VersionException' was thrown.
    DarkRift.Transmission.HandshakeProtocol.GetNoBytesOfHandshake (Byte version)
    DarkRift.DarkRiftConnection.Connect (System.String ip, Int32 port)
    DarkRift.DarkRiftAPI.Connect (System.String ip, Int32 port)
    Network_Manager.Start () (at Assets/DarkRift/NetworkManager/Network_Manager.cs:15)



    I got the mysql connector plugin working fine but this part has me stumped

    (The error currently in this line only DarkRiftAPI.Connect(IP, Port); so perhaps something wrong with the port? I doubt its the ip. Maybe there's a setting in mysql thats preventing access that I need to switch off?)
     
    Last edited: Dec 4, 2017
  29. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    Thank you!Jamster
    But i have other probem:
    How to sent a class object(parameter is data) form sever to client?
    I use:
    Code (CSharp):
    1.             foreach(ConnectionService cons in Rooms[3].players.Keys){
    2.  
    3.                 cons.SendReply(0, 1, seed);
    4.             }
    but error message is need to Serializable。

    if i add 【Serializable】in the seed(class object),but other error message
     
  30. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    VersionExceptions are almost exclusively an internal problem so you're best bet is to first make sure you've got the latest DarkRift because there's been a few fixes around them :)

    Your class needs to have the [Serializable] attribute on it like so:
    Code (csharp):
    1. [Serializable]
    2. class MyClass
    3. {
    4. ...
    5. }
    Sorry about the delays,

    Jamie
     
  31. Slaghton

    Slaghton

    Joined:
    Sep 9, 2013
    Posts:
    139
    (Ah, I don't have the Y-Const script, maybe that's causing a problem. Some scripts appear different in the login plugin download vs the youtube vid so guess I need to try and figure out whats missing or needed still)


    Main problem atm is nothing happening when I click on the login button or create account button. In the youtube video it appears a message pops up on server console when clicking either but nothing happens and no more information to go on to figure it out :\.

    (did a quick debug.log and the buttons are registering at least)
     
    Last edited: Dec 5, 2017
  32. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    Hi Jamster:
    I I have already done that。
    Add the class [Serializable].
    But receive data in Unity has error message:



    FileNotFoundException: Could not load file or assembly 'myLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
    System.AppDomain.Load (System.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/AppDomain.cs:746)
    System.AppDomain.Load (System.String assemblyString) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/AppDomain.cs:728)
    (wrapper remoting-invoke-with-check) System.AppDomain:Load (string)
    System.Reflection.Assembly.Load (System.String assemblyString) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/Assembly.cs:576)
    System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetDeserializationType (Int64 assemblyId, System.String className) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:832)
    System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadTypeMetadata (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:637)
    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/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:269)
    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/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:195)
    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/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:223)
    System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (BinaryElement element, System.IO.BinaryReader reader) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:130)
    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/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:104)
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179)
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)
    DarkRift.Transmission.TransmissionProtocol.DecodeMessageData (System.Byte[] bytes)
    DarkRift.Transmission.TransmissionProtocol.DecodeMessage (System.Byte[] bytes)
    DarkRift.DarkRiftConnection.ReadBodyCallback (System.Byte[] bytes)
    Rethrow as Exception: An Exception was raised in a background thread.
    DarkRift.DarkRiftConnection.Receive ()
    DarkRift.DarkRiftAPI.Receive ()
    DarkRiftReceiver.Update () (at Assets/DarkRift/DarkRift/Plugins/DarkRiftReceiver.cs:11)
     
  33. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    OK,I have solved it
    Thank u very mach!
     
    Jamster likes this.
  34. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    Hi Jamster

    How many people can be carried on a single-core server at the same time?

    Is that free version only 20 people online at the same time?
     
    Last edited: Dec 8, 2017
  35. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Only 20 users can be online at a time with the free version. Pro allows 200 and Extreme allows unlimited :)
     
  36. gugua

    gugua

    Joined:
    Jan 11, 2013
    Posts:
    32
    Hi Jamster!
    If i hava a mmo game and 3000 users online at the same time.
    What kind of performance server(VPS)?Cpu and Memory(in Extreme version)?
     
    Last edited: Dec 11, 2017
  37. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    I don't know, you'd need to try and see because your logic is going to dictate that more than DarkRift will.

    If you're sending very few messages then you might be able to use one beefy server to do everything. You're more likely to use a cluster of servers though but I can't give any estimates on what you'll need.
     
  38. GSD_Corey_F

    GSD_Corey_F

    Joined:
    Oct 10, 2017
    Posts:
    3
    Hello!
    I am having the same issue that you have given the solution to in the above quote. I'm trying to use data.DecodeData(); and am getting the same serialization error. I have read your solution over many times and cannot figure out exactly what you're trying to say. You say that I need to convert the reader to a writer. I'm imagining that I need to read everything from the data, convert that reader to a writer, and then set data.data = the new writer.
    If that is correct, this is not possible, nor does that really make sense when I am trying to READ the data to begin with, not write it. I cannot read data.data without using Decode.Data(); so how would I go about doing this in code? Maybe I am misunderstanding your solution, but if I am not, I do not see how it is possible to read the data with a DarkRiftReader when I cannot do that without using data.DecodeData();.

    EDIT:
    I didn't really specify what I was exactly trying to do, so I will detail it here.
    I am trying to use an embedded server with custom serialization.
    On the server, I am trying to read information from data.data.
    When I DON'T use data.DecodeData(); I get a null reference when I try to read from data using a DarkRiftReader.
    When I DO use data.DecodeData(); I get a serialization error, but the code continues and is able to read from data using a DarkRiftReader.
    I am looking for a solution on how to get rid of this serialization error and cannot figure out what the solution you suggested in my quote is trying to say.
    Hope that clears things up a bit :)
     
    Last edited: Dec 14, 2017
  39. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    Firstly, you must call DecodeData() to read the contents of it as you want to. However, when you do that, the contents of data.data is (as you expect) a DarkRiftReader.

    DarkRift then leaves your event handler and tries to serialize the contents of data.data to send on to the other clients but it cannot do this because DarkRiftReaders can't be serialized (it doesn't make sense to, DarkRiftWriters are the things that gets serialized, DarkRiftReaders are the opposite and get deserialized). DarkRift has to throw an error.

    The way around this is to tell DarkRift what you want to be serialized and sent to the others when it exits the handler. To do this you need to give it a DarkRiftWriter (since they're the one that gets serialized). In your situation, you want to decode the data and then make sure that you copy the information you want sent on into data.data as a writer.

    It's not ideal, granted, but DarkRift 2 gets rid of this mess!
     
    GSD_Corey_F likes this.
  40. GSD_Corey_F

    GSD_Corey_F

    Joined:
    Oct 10, 2017
    Posts:
    3
    Thanks for the reply!
    I understand a little better but I get confused towards the end. Sorry!

    So, here's a simple snippet of code that I use to send a message to the server.

    Code (CSharp):
    1. using (DarkRiftWriter writer = new DarkRiftWriter())
    2. {
    3.      writer.Write(ID);
    4.      writer.Write(transform.position.x);
    5.      writer.Write(transform.position.y);
    6.      writer.Write(transform.position.z);
    7.      writer.Write(transform.rotation.x);
    8.      writer.Write(transform.rotation.y);
    9.      writer.Write(transform.rotation.z);
    10.      DarkRiftAPI.SendMessageToServer(XTagIndex.ObjectUpdate, XTagIndex.ObjectUpdatesSubjects.Transform, writer);
    11. }
    And here is a small snippet of code where I try to read that message from the server, and send out another message to other clients.

    Code (CSharp):
    1. else if (data.tag == XTagIndex.ObjectUpdate)
    2. {
    3.             if (data.subject == XTagIndex.ObjectUpdatesSubjects.Transform)
    4.                {
    5.                 Debug.Log("Message was of type ObjectUpdate, Transform!");
    6.  
    7.                 data.DecodeData();
    8.                 using (DarkRiftReader reader = (DarkRiftReader)data.data)
    9.                 {
    10.                     uint objectID = reader.ReadUInt32();
    11.                     Debug.Log("Server read object ID as : " + objectID.ToString());
    12.                     Vector3 pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
    13.                     Debug.Log("Server read object Position as : " + pos.ToString());
    14.                     Quaternion rot = new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 1);
    15.                     Debug.Log("Server read object Rotation as : " + rot.ToString());
    From there I do something similar to the first snippet of code to send out a message to all clients (aside from the one who sent it)

    So, if I understand correctly so far, in order to use DecodeData() to read it, data has to be of type DarkRiftWriter, which is not the case to begin with as it is received by the event handler as a DarkRiftReader.
    Breaking what you said down step by step, this is what I gather so far.
    1. decode the data with data.DecodeData()
    2. Set data.data to a new DarkRiftWriter that contains what data.data contained before
    And that's where I either misunderstand or get lost.
    Issue with step 1, I cannot use data.DecodeData() without receiving the serialization error. I'm assuming that it needs to be a DarkRiftWriter at this step already.
    I guess my question is how do I exactly do the conversion from DarkRiftReader to DarkRiftWriter while assigning data.data to it? And from there, how would I read the data when it is now of type DarkRiftWriter?
    I'm sorry for my misunderstanding as I'm sure I'm making this much harder than it really is. Maybe a small generic code sample of the conversion would help?
     
  41. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    OK, perhaps I've misunderstood.

    It sounds like you're doing the right thing but it's just the error that's the problem. What exactly is the error you get?

    When call DecodeData it should give you a DarkRiftReader (because that's what you receive data with) before you leave your method though you must replace data.data with a DarkRiftWriter (because that's what you send data with).

    Untested but will hopefully make it clearer
    Code (csharp):
    1. data.DecodeData();
    2. using (DarkRiftReader reader = (DarkRiftReader)data)
    3. {
    4.     //The client should have sent a vector
    5.     Vector3 myVector = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
    6.  
    7.     //Do stuff with vector
    8.  
    9.     //Package vector back up to send to other clients
    10.     DarkRiftWriter writer = new DarkRiftWriter()
    11. [LEFT][FONT=Helvetica][COLOR=rgb(51, 51, 51)]    writer.Write(myVector.x);
    12.     writer.Write(myVector.y);[/COLOR][/FONT][/LEFT]
    13.     writer.Write(myVector.z);
    14.  
    15.     data.data = writer
    16. }
     
    GSD_Corey_F likes this.
  42. GSD_Corey_F

    GSD_Corey_F

    Joined:
    Oct 10, 2017
    Posts:
    3
    AHHH! You're a life saver. My issue turned out to be the fact that I was sending data from the server the wrong way like a dummy. I was trying to send a writer when I needed to send data.data instead, after setting data.data to the writer I created. I changed 2 lines of code and the issue was resolved. Thank you so much for the help!
     
    Jamster likes this.
  43. StarOfDoom

    StarOfDoom

    Joined:
    Feb 25, 2017
    Posts:
    11
    So I know there was talk of a "Dark Rift 2" over a year ago. Anything come of that?
     
  44. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
  45. PingDadTool

    PingDadTool

    Joined:
    Mar 30, 2022
    Posts:
    1
    PingDad is 100% Free to use, feel free to Ping Your sites, web journals and other web related contents. It will ping your site and will show you failed and success results. It helps Major Search Engines, RSS Feed Directories to know that your website has fresh contents. Pinging is a method to gain fame for your blogs, index links and contents. Stop waiting, start pinging, submit your URL, and link/blog details and click on ping.
    https://pingdad.com/