跳到主要內容

精選

遊戲伺服器2025年初架設與研究part11-Websocket與Unity的登入+聊天室精簡版

 那先前使用Websocket的內容經過一段時間研究 也算是有了一些進展 並且先前也有人對於websocket那篇筆記一次講的內容有點太多,會不好理解 導致可能中途就遭遇了一些BUG比較難解決的 那這次就把相關的內容進行了一些精簡 讓大家可以更快速的架設好websocket的內容 當然這邊也可以當作是不同的使用方式 隨著學習各種不同的資訊,也能更清楚地理解這些其實是不同的使用方式。 因此,這方面完全可以多學幾種,以便因應各種不同的情況。 首先是 Unity 專案的準備 我們必須把常用的 Websocket 插件準備好(Unity) https://github.com/endel/NativeWebSocket 這是較多人使用的 Websocket 插件 可以根據Github那邊寫的資訊進行操作 匯入 到Unity專案內 那我這邊也直接提供方式 首先在你的Unity專案中,上方的選單選擇Window 底下選到 Package Manager 打開Package Manager 點選有URL的選項( Install package from git URL ) 接著請在這個URL框內輸入對應的內容 也就是 https://github.com/endel/NativeWebSocket.git#upm 輸入好之後就點擊最右邊的install安裝就好了 安裝好會如圖這樣我們可以看到 Native WebSockets 插件會在這個位置 如果需要更新,可以在右邊的選單點Update即可 這樣在Unity內就可以使用Websocket相關的語法了 接著我們回到伺服器的地方,也就是我們的 Ubuntu server 首先確保在虛擬環境當中進行安裝 websocket 插件 簡單的確認方式就是看現在輸入的位置前方有無 (venv) 確認好之後可以進行安裝pip install websockets 接著請在想要執行的位置新增一個python檔案(.py) 我這邊是在自己電腦的python專案內新增了一個python檔案main.py 內容如下 import asyncio import websockets import json co...

遊戲伺服器2025年初架設與研究part5結合Unity的Client端發送POST來讓Server對應資料記錄到資料庫或更新資料庫

 那根據先前的測試

已經可以讓伺服器開機的時候自動啟用指定的腳本(py)

那某方面來說已經算是個有功能的伺服器了

接下來我們就是要來調整一下功能

讓我們的遊戲,也就是Client端可以進行連接(Client端對應Server端,也就是通常的使用者端)

稱呼的問題似乎在許多地方有不同的習慣,總之就是使用者通常能接觸到的部分

以遊戲來說就是玩遊戲的時候執行的那些應用程式,就歸類成client端

那我們接下來可以先把準備好的Unity專案打開了

當然這邊就是打開各自準備的Client端就好

即便是空的Unity專案也可以

而Unity的專案一般是透過C#來撰寫的,我這邊也會使用C#的範例

這邊單純的使用Unity預設的腳本內容來調整就好
在專案區域右鍵Create>MonoBehaviour Script
接下來取個合適的名稱來使用
由於功能單純就是傳資料給server並且收回應,所以可以取的SendMessage之類的
又或是你打算拿來登入傳訊息,也可以取的Login之類的
當然也可以當作遊戲管理器的一部分,取作GameManager

新增好C#腳本後點兩下打開

正常的話這邊專案就會替你打開Microsoft Visual Studio(如果有安裝的話)
那這邊就只是編輯軟體,所以可以打開自己習慣的編輯器就好(IDE)
如Vs code或是其它的

那Unity這邊就已經準備好了
接下來先回到伺服器那邊
跟上次類似,我們要先準備要寫入資料庫的表格

先進到我們要添加資料庫的路徑(登入對應User)
當然也可以使用先前提到的pgAdmin進行執行指令添加
例如我這邊添加的範例如下

  
CREATE TABLE players (
    player_id SERIAL PRIMARY KEY,
    username TEXT UNIQUE NOT NULL,
    record1 TEXT NOT NULL,
    record2 TEXT NOT NULL,
    score1 BIGINT NOT NULL,
    score2 BIGINT NOT NULL,
    score3 BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
當然大家可以根據需求調整
主要就是表格名稱players等等會用到

那接下來就是回到先前的python腳本中開始進行撰寫
首先Sql連線,這部分也可以與上次相同就好,記得裡面的資料要替換成自己的

  
def get_db_connection():
    return psycopg2.connect(
    host="localhost",
    database="use_db",
    user="your_user",
    password="your_password"
)
那上面該引入或是導入的也記得要補上,例如這些
from flask import Flask
import psycopg2
from datetime import datetime

接下來是我們主要的內容,也就是接收client端傳來的封包
暫定是使用POST,在我們主要的python檔案內加入以下程式碼
當然先前的sql連線也要有,那這邊要注意的也是/game_test這個雖然可以自己定義,但是等等會用到,所以要記好自己取什麼


  
@app.route("/game_test", methods=["POST"])
def start_player():
    try:
        data = request.get_json()
        username = data.get("username")
        record1 = data.get("record1")
        record2 = data.get("record2")
        score1 = data.get("score1")
        score2 = data.get("score2")
        score3 = data.get("score3")
        created_at = datetime.now(taipei)
        conn = get_db_connection()
        with conn.cursor() as cur:
            cur.execute(
                """
            INSERT INTO players             (username, record1, record2, score1, score2, score3, created_at)
            VALUES (%s, %s, %s,%s, %s, %s, %s)
            ON CONFLICT (username) DO UPDATE SET
                record1 = EXCLUDED.record1,
                record2 = EXCLUDED.record2,
                score1 = EXCLUDED.score1,                 score2 = EXCLUDED.score2,
                score3 = EXCLUDED.score3,                 created_at = EXCLUDED.created_at
                """,
                (username, record1,record2, score1, score2, score3, created_at)
            )

            conn.commit()
        conn.close()
        return jsonify({"status": "success"}), 200
    except Exception as e:
        conn.rollback()
        import traceback
        traceback.print_exc()
        return jsonify({"status": "error", "message":str(e)}), 500
主要我們這段程式碼就可以解析Client端傳來的資訊,並且把對應的欄位資料獲取
接下來我們要進行寫入資料庫的動作
這邊寫入則會判斷username是否存在,如果存在就"更新資料"
如果不存在,才寫入一筆新的資料
這邊添加好的python可以透過遠端丟到伺服器,用跟先前的方式更新執行,又或是新增一個新的服務來執行,或是單純用原始的方式python3去執行這個檔案

執行好之後,我們就可以回到Unity的專案這邊(Client端)
首先using的部分
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
先宣告自己網域名稱,後面連接剛剛在app.route後面接的名稱
private string serverUrl = "https://自己的網域/game_test";

接著在Start的地方加入

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

最後就是主要內容

  
IEnumerator SendStartInfo()
{
// 建立要送出的 JSON 字串
string jsonData = JsonUtility.ToJson(new PlayerInfo()
{
username = "testName2",
record1 = "紀錄文字1",
record2 = "紀錄文字2",
score1 = 1234,
score2 = 2345,
score3 = 6789
});
using (UnityWebRequest www = new UnityWebRequest(serverUrl, "POST"))
{
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData);
www.uploadHandler = new UploadHandlerRaw(bodyRaw);
www.downloadHandler = new DownloadHandlerBuffer();
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
#if UNITY_2020_1_OR_NEWER
if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError)
#else
    if (www.isNetworkError || www.isHttpError)
#endif
{
Debug.LogError("Error sending data: " + www.error);
}
else
{
//Debug.Log("Response: " + www.downloadHandler.text);
}
}
}

// 用來序列化成 JSON 的類別
[System.Serializable]
private class PlayerInfo
{
public string username;
public string record1;
public string record2;
public long score1;
public long score2;
public long score3;
}
那這樣我們腳本就存檔,完成
可以把它掛在任意場景物件上執行測試了~
這邊主要幾個注意的點,首先就是要用StartCoroutine來執行IEnumerator的function
另外要轉json的格式要記得加上可序列化
也就是[System.Serializable]
接下來就是看Unity執行後的結果
我們正常運作的話就可以看到在資料庫多寫入了一筆資料
並且是我們Unity裡面寫入的資料,這邊就可以替換任何大家想要讓Client端送給Server的資料
同樣的也能測試如果同一個玩家啟動第二次是否能正確覆寫資料
正確邏輯應該要會找到同一筆玩家的資料庫資料進行後面的資料更新
如果寫入了一筆新的資料則是邏輯有誤,可以回去檢查是不是哪邊有寫錯了~

這次就先分享到這邊,如果有疑問也可以直接發問,或是有什麼想要糾正的也歡迎留言~




留言