it-swarm.com.de

So stellen Sie von Unity aus eine Verbindung zur Datenbank her

Ich versuche über Unity eine Verbindung zu einer MS SQL-Datenbank herzustellen. Wenn ich jedoch versuche, eine Verbindung zu öffnen, erhalte ich eine IOException: Verbindung verloren.

Ich habe System.Data.dll aus Unity\Editor\Data\Mono\lib\mono\2.0 importiert. Ich verwende den folgenden Code:

 using UnityEngine;
 using System.Collections;
 using System.Data.Sql;
 using System.Data.SqlClient;

 public class SQL_Controller : MonoBehaviour {

     string conString = "Server=myaddress.com,port;" +
             "Database=databasename;" +
             "User ID=username;" +
             "Password=password;";

     public string GetStringFromSQL()
     {
         LoadConfig();
         string result = "";

         SqlConnection connection = new SqlConnection(conString);
         connection.Open();
         Debug.Log(connection.State);
         SqlCommand Command = connection.CreateCommand();
         Command.CommandText = "select * from Artykuly2";
         SqlDataReader ThisReader = Command.ExecuteReader();
         while (ThisReader.Read())
         {
             result = ThisReader.GetString(0);
         }
         ThisReader.Close();
         connection.Close();

         return result;
     }
 }

Dies ist der Fehler, den ich bekomme:

IOException: Connection lost
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacketHeader ()
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacket ()
Mono.Data.Tds.Protocol.TdsComm.GetByte ()
Mono.Data.Tds.Protocol.Tds.ProcessSubPacket ()
Mono.Data.Tds.Protocol.Tds.NextResult ()
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Rethrow as TdsInternalException: Server closed the connection.
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Mono.Data.Tds.Protocol.Tds70.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)
Mono.Data.Tds.Protocol.Tds80.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)

Bitte ignorieren Sie alle Sicherheitsrisiken bei diesem Ansatz. Ich MUSS dies zum Testen tun. Die Sicherheit wird später kommen. Vielen Dank für Ihre Zeit.

6
MLazowski

Bitte ignorieren Sie Sicherheitsrisiken bei diesem Ansatz

Mach es nicht so. Es ist egal, ob die Sicherheit vorher oder nachher kommt. Sie werden das erneute Schreiben des gesamten Codes beenden, da das Kennwort in Ihrer Anwendung fest codiert ist, das leicht dekompiliert und abgerufen werden kann . ). Stellen Sie die Verbindung jetzt korrekt her, damit Sie nicht die gesamte Anwendung neu schreiben müssen.

Führen Sie Ihren Datenbankbefehl auf Ihrem Server mit PHP, Perl oder einer anderen Sprache aus. Dies sollte jedoch auf dem Server geschehen.

Verwenden Sie in Unity die Klasse WWW oder UnityWebRequest , um mit diesem Skript zu kommunizieren. Anschließend können Sie Informationen senden und empfangen von Unity zum Server. Es gibt viele Beispiele aus dort . Trotzdem müssen Sie Ihre eigene Sicherheit implementieren, aber dies ist viel besser als das, was Sie jetzt haben.

Sie können Daten auch mehrfach mit json empfangen.

Unten finden Sie ein vollständiges Beispiel aus this Unity wiki. Es zeigt, wie Sie mit einer Datenbank in Unity mithilfe von PHP auf der Serverseite und Unity + C # auf der Clientseite interagieren.

Serverseitig :

Punktzahl mit gU hinzufügen:

<?php
        // Configuration
        $hostname = 'localhot';
        $username = 'yourusername';
        $password = 'yourpassword';
        $database = 'yourdatabase';

        $secretKey = "mySecretKey"; // Change this value to match the value stored in the client javascript below 

        try {
            $dbh = new PDO('mysql:Host='. $hostname .';dbname='. $database, $username, $password);
        } catch(PDOException $e) {
            echo '<h1>An error has ocurred.</h1><pre>', $e->getMessage() ,'</pre>';
        }

        $realHash = md5($_GET['name'] . $_GET['score'] . $secretKey); 
        if($realHash == $hash) { 
            $sth = $dbh->prepare('INSERT INTO scores VALUES (null, :name, :score)');
            try {
                $sth->execute($_GET);
            } catch(Exception $e) {
                echo '<h1>An error has ocurred.</h1><pre>', $e->getMessage() ,'</pre>';
            }
        } 
?>

Punktzahl mit PDO abrufen:

<?php
    // Configuration
    $hostname = 'localhost';
    $username = 'yourusername';
    $password = 'yourpassword';
    $database = 'yourdatabase';

    try {
        $dbh = new PDO('mysql:Host='. $hostname .';dbname='. $database, $username, $password);
    } catch(PDOException $e) {
        echo '<h1>An error has occurred.</h1><pre>', $e->getMessage() ,'</pre>';
    }

    $sth = $dbh->query('SELECT * FROM scores ORDER BY score DESC LIMIT 5');
    $sth->setFetchMode(PDO::FETCH_ASSOC);

    $result = $sth->fetchAll();

    if(count($result) > 0) {
        foreach($result as $r) {
            echo $r['name'], "\t", $r['score'], "\n";
        }
    }
?>

Cross Domain Policy auf dem Server aktivieren:

Diese Datei sollte "crossdomain.xml" heißen und sich im Stammverzeichnis Ihres Webservers befinden. Für Unity muss für Websites, auf die Sie über eine WWW-Anfrage zugreifen möchten, eine domänenübergreifende Richtlinie gelten.

<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

Client/Unity-Seite :

Der Client-Code von Unity stellt eine Verbindung zum Server her, interagiert mit PDO und fügt Punkte hinzu oder ruft Punkte ab, je nachdem, welche Funktion aufgerufen wird. Dieser Clientcode wurde geringfügig geändert, um mit der neuesten Unity-Version zu kompilieren.

private string secretKey = "mySecretKey"; // Edit this value and make sure it's the same as the one stored on the server
public string addScoreURL = "http://localhost/unity_test/addscore.php?"; //be sure to add a ? to your url
public string highscoreURL = "http://localhost/unity_test/display.php";

//Text to display the result on
public Text statusText;

void Start()
{
    StartCoroutine(GetScores());
}

// remember to use StartCoroutine when calling this function!
IEnumerator PostScores(string name, int score)
{
    //This connects to a server side php script that will add the name and score to a MySQL DB.
    // Supply it with a string representing the players name and the players score.
    string hash = Md5Sum(name + score + secretKey);

    string post_url = addScoreURL + "name=" + WWW.EscapeURL(name) + "&score=" + score + "&hash=" + hash;

    // Post the URL to the site and create a download object to get the result.
    WWW hs_post = new WWW(post_url);
    yield return hs_post; // Wait until the download is done

    if (hs_post.error != null)
    {
        print("There was an error posting the high score: " + hs_post.error);
    }
}

// Get the scores from the MySQL DB to display in a GUIText.
// remember to use StartCoroutine when calling this function!
IEnumerator GetScores()
{
    statusText.text = "Loading Scores";
    WWW hs_get = new WWW(highscoreURL);
    yield return hs_get;

    if (hs_get.error != null)
    {
        print("There was an error getting the high score: " + hs_get.error);
    }
    else
    {
        statusText.text = hs_get.text; // this is a GUIText that will display the scores in game.
    }
}

public string Md5Sum(string strToEncrypt)
{
    System.Text.UTF8Encoding ue = new System.Text.UTF8Encoding();
    byte[] bytes = ue.GetBytes(strToEncrypt);

    // encrypt bytes
    System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
    byte[] hashBytes = md5.ComputeHash(bytes);

    // Convert the encrypted bytes back to a string (base 16)
    string hashString = "";

    for (int i = 0; i < hashBytes.Length; i++)
    {
        hashString += System.Convert.ToString(hashBytes[i], 16).PadLeft(2, '0');
    }

    return hashString.PadLeft(32, '0');
}

Dies ist nur ein Beispiel dafür, wie dies richtig gemacht wird. Wenn Sie eine Sitzungsfunktion implementieren und auf Sicherheit achten müssen, lesen Sie das OAuth 2.0 -Protokoll. Es sollten Bibliotheken vorhanden sein, die Ihnen den Einstieg in das OAuth -Protokoll erleichtern.

12
Programmer

Eine Alternative wäre, einen eigenen dedizierten Server in einer Eingabeaufforderung zu erstellen, um Ihre Kommunikation durchzuführen und die Verbindung zwischen Unity und Händel Multiplayer und SQL-Kommunikation herzustellen. Auf diese Weise können Sie bei allem bleiben, das in einer Sprache erstellt wird. Aber eine ziemlich steile Lernkurve.

1
Jason

Die Einheit ist die Spielmaschine.

das ist richtig, was die Antwort sagt.

einige Domänen müssen jedoch eine direkte Verbindung zur Datenbank herstellen.

Sie sollten diesen Datenbankzugriff nicht direkt in der Spieldomäne ausführen.

Wie auch immer, das Problem wird durch den nicht-englischen Computernamen verursacht.

Ich hatte vor dem Projekt eine Art von folgenden Fehlern.

IOException: Connection lost
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacketHeader ()
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacket ()
Mono.Data.Tds.Protocol.TdsComm.GetByte ()
Mono.Data.Tds.Protocol.Tds.ProcessSubPacket ()
Mono.Data.Tds.Protocol.Tds.NextResult ()
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Rethrow as TdsInternalException: Server closed the connection.
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Mono.Data.Tds.Protocol.Tds70.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)
Mono.Data.Tds.Protocol.Tds80.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)

Und nachdem Sie den Computernamen auf ENGLISCH geändert haben, funktioniert es.

Ich weiß nicht, wie es geht. Aber es funktioniert.

Die Datei "System.Data.dll" von Mono weist einige Probleme mit dem Namen "PC" auf, die NICHT ENGLISCH sind.

Also zumindest Unity-Projekt.

Sie sollten Ihrem Kunden mitteilen, dass sein Computername nicht NON-ENGLISH lautet.

Ich kenne keine Leute in Mono, die diese Angelegenheit kennen oder nicht.

0
Justin Jeon