[Unity exports WebGL and connects to the database through Nginx in Linux Pagoda] Use UnityWebRequest and WebAPI (php service) to execute mysql commands

foreword

  • To do a project Unity, WebGLthe project that needs to be exported can interact with the database. Here it means insertthat
    the project that can achieve "command is successful" has been successfully deployed under the Tencent cloud server Linuxthrough Nginxthe deployment of Pagoda.
  • So I chatGPTurgently learned other related technologies to realize the function of interacting with the database .

Option 1, MySql.Data.MySqlClient

Preparation

  • The first solution is relatively simple, directly imported in C#the code
using System.Data;
using MySql.Data.MySqlClient;

The first header file can be automatically and directly imported in the newer Unity Editor version , otherwise you need to find it in the path of the specific editor.
The path of the editor can be opened directly in UnityHub
insert image description here
insert image description here

  • The header file needs to be placed in Pluginsthe folder DLLas follows
MySql.Data.dll
I18N.CJK.dll
I18N.dll
I18N.West.dll

Among MySql.Data.dllthem , download here , choose the third version here to download successfully.
The next four files are typically in these directories:
insert image description here

  • Then, put the above dll into this folder. Common sense operation.
    insert image description here

database part

  • Add the database at this location of Linuxthe pagoda
    . Note that the difference in encoding is supported on
    utf8mb4 the basis of , that is, those emoji encodings support various characters across the country, including Chinese, and more support Chinese encoding, of which only Chinese is supported . Note that we choose here , otherwise the encoding will need to be adjusted later. kind of hard.utf8most bytes 4
    utf8
    gbkgbk2312
    utf8
  • Remember the database name, username and password here. Note that the account and rootaccount password are different.
    insert image description here
  • Then Navicatat , connect to the database and create the tables you need.
    Maybe the connection failed at the first creation or other problems, you need to modify it as follows:
    modify access rights :
    insert image description here
    database scheduled backup :
    insert image description here
    release port : the default database uses port 3306No. It needs to be released at LinuxPagoda and Tencent Cloud Server.
    insert image description here
  • Check the port number here.
    insert image description here

code part

  • The code part is simple. After introducing the necessary header files, declare a MySqlConnection connection , then call ConnectSQL()the code, given the database name, port number, username and password and connect.
    QuerySet()code call, execute sqlStringcommand
	using System.Data;
	using MySql.Data.MySqlClient;
	
    public static string dbName = "XXdb";
    public static string tableName = "XXT";
    public static string host = "IP";
    public static string uname = "aniDB";
    public static string psw = "your password";
    public static string port = "your port";
	private static MySqlConnection con;
	
    public void ConnectSQL()	// 直接复制粘贴使用即可
    {
    
    
        try
        {
    
    
            string mySqlString = string.Format("Database={0};Data Source={1};User Id={2};Password={3};port={4}"
                , dbName, host, uname, psw, port);
            con = new MySqlConnection(mySqlString);
            con.Open();
        }
        catch (Exception e)
        {
    
    
            throw new Exception("服务器连接失败,请重新检查MySql服务是否打开。" + e.Message.ToString());
        }
    }

    public void CloseSql()	// 直接复制粘贴使用即可
    {
    
    
        if (con != null)
        {
    
    
            con.Close();
            con.Dispose();
            con = null;
        }
    }

    public void RawQuery(int stage, int val)	// 为一个具体的插入例子
    {
    
    
        DateTime dateTime = DateTime.Now;
        string sqlstr = string.Format("INSERT INTO {0} VALUES('{1}',{2},'{3}','{4}','{5}',{6},'{7}') "
        , tableName, id, stage, user_name, college_name, tel, val, dateTime);
        QuerySet(sqlstr);
    }

    private DataSet QuerySet(string sqlString)	// 直接复制粘贴使用即可
    {
    
    
        if (con.State == ConnectionState.Open)
        {
    
    
            DataSet ds = new DataSet();
            try
            {
    
    
                MySqlDataAdapter mySqlAdapter = new MySqlDataAdapter(sqlString, con);
                mySqlAdapter.Fill(ds);
            }
            catch (Exception e)
            {
    
    
                throw new Exception("SQL:" + sqlString + "/n" + e.Message.ToString());
            }
            finally
            {
    
    
            }
            return ds;
        }
        return null;
    }

in conclusion

  • The local call is successful, and the data in the database is successfully inserted.
    WebGLIn the project, the data in the database fails to be inserted
    . Reason:unity在webgl的平台下无法支持直连MySql
    insert image description here

Solution 2: Create an intermediate php service and call it through UnityWebRequest to execute the mysql command

  • Haha, it's so convoluted, but it chatGPTis a seemingly feasible solution that I provided when I was most helpless.
    But I haven’t learned these two things before
    , it’s okay, let’s go step by step

php write

  • Through the guidance chatGPTof , we have such a index.phpfile
<?php

$servername = "your IP";
$username = "your user name";
$password = "your password";
$dbname = "your db name";

// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);

// 检查连接是否成功
if ($conn->connect_error) {
    
    
    die("连接失败: " . $conn->connect_error);
}

// 从HTTP请求中读取JSON数据
$json_data = file_get_contents('php://input');

// 将JSON数据解码为PHP数组
$data = json_decode($json_data, true);

// 插入数据到数据库表格
$sql = "INSERT INTO aniT VALUES ('".$data['id']."', '".$data['stage']."','".$data['college']."','".$data['tel']."','".$data['value']."','".$data['time']."')";
if ($conn->query($sql) === TRUE) {
    
    
    echo "插入成功";
} else {
    
    
    echo "Error: " . $sql . "<br>" . $conn->error;
}

// 关闭连接
$conn->close();
?>
  • The above code httpRequestpasses in json data, then converts it into $dataa php array, then combines it into $sqla mysql statement (a string), and finally executes it.
    insert image description here
  • For the first test, it may be troublesome for a large number of code tests. It is recommended to use the following code for the first time to test
<?php
phpinfo();
?>

php deployment

  • Deployment is such a headache.
    First of all, make sure that your Linuxpagoda has downloaded this PHP, 5.Xthis version can actually be used.
    insert image description here
  • Open the configuration file, we only need to pay attention to the FPM configuration file
    to view listen = XXXX, note that what is listening here is not a port but a portsock , copy the sock
    insert image description here
  • Open Nginxthe configuration file, select configuration modification , and scroll down to serverthis section.
    We have learned locationabout htmlthe basic configuration of , and we have successfully opened WebGLthe project .
    Here we need to deploy phpthe file , which is quite different...
    insert image description here
  • If you haven’t configured it before, you need to add this section and
    fastcgi_passfill it in later, unix:and then
    copy the monitoring sock just now
    , otherwise I won’t be able to open it...
        location ~ \.php$ {
    
    
          fastcgi_pass   unix:/tmp/php-cgi-56.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME     $document_root$fastcgi_script_name;
          include        fastcgi_params;
        }
  • Then I index.phppassed to the root directory, which is /www/wwwrootunder the directory. You can
    try to see if the access is successful. I encountered the following problem. Situation 1: 502 BadGate is estimated to be that the port number has not been released, and there is no permission to access. Situation 2: 404: The hyperlink direct failed. Generally, your file is placed in the wrong directory, or the directory configuration is wrong, or the secondary directory is entered incorrectly. Situation 3: file not found The file is placed in the wrong directory, or the directory configuration is wrong. Situation 4: 403 forbidden Looks like a permissions issueip/index.php





    insert image description here

(Note: After the php is deployed, it is similar to a web page, although it is called WebAPI and provides other services)
(but it does not seem to be a complete WebAPI project)

  • Generally, after trying many times and understanding the configuration file, you can access successfully.

C# coding

  • Let's go back here Unityand write some code in the script.
    We need to use UnityWebRequest to access the above phpservice.
    First, you need to import a new header file. using UnityEngine.Networking;
    The code part is as follows:
    public void RawQuery(int stage, int val)	// 一个测试函数
    {
    
    
        StartCoroutine(Insert(url, id, stage, college_name, tel, val, DateTime.Now));
    }
    // 具体的插入myqsl命令的函数
    IEnumerator Insert(string url, string id, int stage, string college, string tel, int value, DateTime time)
    {
    
    
        // 创建JSON数据
        string json = "{\"id\":\"" + id + "\",\"stage\":" + stage + ",\"college\":\"" + college + "\",\"tel\":\"" + tel + "\",\"value\":" + value + ",\"time\":\"" + time.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
        // Debug.Log(json);
        UnityWebRequest request = UnityWebRequest.Post(url, json);

        // 创建HTTP请求
        byte[] bodyRaw = Encoding.UTF8.GetBytes(json);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        // 发送HTTP请求
        yield return request.SendWebRequest();
        if (request.result == UnityWebRequest.Result.Success)
        {
    
    
            Debug.Log("Request successful!");
        }
        else
        {
    
    
            Debug.Log("Request failed!");
        }
        request.Dispose();

    }
  • So here comes the question again.
    Doubt 1: WebGLIs IEnumerator n’t ? Why can it be used here?
    insert image description here
    (You boy, the liver is jumping repeatedly, right!)
    Well, after my thinking, I came to the following conclusion:
    Although WebGLit is not supported IEnumerator (public opinion, and chatGPT's reply)
    although WebGLit is supported UnityWebRequest(this is in the official documentation of unity Also proposed)
    but UnityWebRequestsupport IEnumerator (WTF?)
    Well, the code and I have one that works.
  • Doubt 2: The weird format string jsonof
    is simply a json stored as a string, and unity transfers the json string to php for subsequent analysis.
    Note: For data in varchar format, quotation marks are required, which is also common sense. If the format is wrong, you will encounter the problem of explosion later (press no table here).

A Native Collection has not been disposed, resulting in a memory leak.

  • Doubt 3: I was notrequest.Dispose(); asked to write this sentence at the beginning . If you don't add it, you will encounter (and always encounter) the lovely at runtime:chatGPT

    A Native Collection has not been disposed, resulting in a memory leak. ……
  • There are no more error messages later, and a new package needs to packManagerbe imported com.entityor something, but it can indeed be seen after importing, and it is found that an error was reported after UnityWebRequest.Post(url, json)entering .
    But after the running phase, there was a check solution. It seems that it can be solved by deleting useless files such as . So I deleted this package again...
    RuntimeError: memory access out of bounds - gatsby development extremely slow
    insert image description here
    dll
  • Um, so what is the reason for it? It has been suggested that various issues can cause this bug . Situation 1: Not dropped Situation 2: Statement syntax error (that is what I encountered...)A Native Collection has not been disposed, resulting in a memory leak. ……


    UnityWebRequest Dispose
    mysql
  • Or a blog recommends the following format:
using(UnityWebRequest request = XXX){
    
    
	XXXX;
}

They say it will automatically use Disposethe method , it might work

Some other problems I still have

  • I found Unityout WebGLthat InputFieldthere is no keyboard for input after clicking on the mobile terminal...
    outrageous, it is said WebGLto support various devices, but the result is only supported in name...
    Some people say that using a virtual keyboard is just typing a code by yourself. There are still people who need to spend 100 100Rto download...
    I have no choice but to cancel the Chinese character input and write a virtual keyboard for digital input by hand. Send it.
  • That is, WebGLit does not support horizontal screen switching on the mobile terminal, keyboard input, basically IEnumerator, some browsers cannot be opened, and some browsers do not support audio playback... The only advantage is that you can download and play when you open the connection.
  • I just need insertthe command . If you need selectthe command , you need POST+ GET, which should be similar in principle. For details, you can also ask Baidu and ChatGPTuse dataSetthe type to store the data from GET.

Guess you like

Origin blog.csdn.net/weixin_45775438/article/details/130116593