2016-08-25 143 views
2

我正嘗試通過Unity連接到MS SQL數據庫。但是,當我嘗試打開連接時,出現IOException:連接丟失。如何從Unity連接到數據庫

我已經從Unity \ Editor \ Data \ Mono \ lib \ mono \ 2.0導入System.Data.dll。我用下面的代碼:

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; 
    } 
} 

這是我的錯誤:

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) 

請忽略這種方法的任何安全隱患,我需要進行測試做到這一點,安全以後還會來。 謝謝你的時間。

回答

4

請忽略任何安全風險,這種做法

不要做這樣。安全性會在之前還是之後出現並不重要。您將重寫整個代碼,因爲密碼在您的應用程序中被硬編碼,可以反編譯和檢索容易。現在以正確的方式進行連接,以便您不必重寫整個應用程序。

在你的服務器上用php,perl或任何你喜歡的語言在服務器上運行你的數據庫命令,但是這應該在服務器上完成。

從Unity開始,使用WWWUnityWebRequest類與該腳本進行通信,然後,您將能夠從Unity向服務器發送和接收信息。有很多examplesthere。即使這樣,你仍然需要實現自己的安全,但是這比現在好得多。

您還可以用json接收數據倍數。

以下是來自this Unity Wiki的完整示例。它展示瞭如何在Unity中使用服務器端的php和客戶端的Unity + C#與數據庫進行交互。

服務器端

添加分數與PDO

<?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>'; 
      } 
     } 
?> 

找回得分與PDO

<?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"; 
     } 
    } 
?> 

服務器上啓用跨域策略:

該文件應命名爲「crossdomain.xml」,並放置在Web服務器的根目錄下。 Unity要求您希望通過WWW請求訪問的網站具有跨域策略。

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

客戶端/統一側

從Unity客戶端代碼連接到服務器,以PDO相互作用並增加或檢索分數取決於哪個函數被調用。此客戶端代碼稍作修改以使用最新的Unity版本進行編譯。

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'); 
} 

這僅僅是如何正確地做到這一點的例子。如果您需要實施會話功能並關心安全性,請查看協議的OAuth 2.0。應該有現有的庫,可以幫助開始使用協議OAuth協議。

+0

我已經設法建立一個連接跟隨你的第一個例子,併發布並從表中獲取結果。謝謝。 – MLazowski

+0

太棒了。很高興你沒有堅持這樣做。 – Programmer