天天看點

C#服務端的微信小遊戲——多人線上角色扮演(九)建立連接配接

C#服務端的微信小遊戲——多人線上角色扮演(九)

  • 建立連接配接
    • 服務端
    • 用戶端

微信小程式是個不錯的平台,用來做手機小遊戲真的很好,簡單、通用性好、友善傳播。

——茂叔

好了,現在我們開始做用戶端了,用戶端選擇微信小程式,是以我們要下載下傳

微信Web開發者工具

是以為什麼說騰訊隻會抄襲呢,一旦自己搞點東西,連取個名字都不會了,這要是洋人搞的,保不齊取個什麼高大上的名字呢……例如TCStadio、TCWARESHOP之類的,一看就覺得高大上。

好吧,中國人就是低調,總之你還沒安裝的話趕緊安裝吧。

申請小程式的過程很簡單,自己去微信公衆平台去查,我這裡就不啰嗦了。

重點就是要記住你的

AppID

AppSecret

這兩個東西。

然後,用戶端第一件要做的事情,那就是與伺服器建立網絡連接配接,根據騰訊公司給出的文檔,

wss

協定的

WebSocket

是唯一的選擇了。

建立連接配接

服務端

那麼,首先是要在伺服器端提供網絡連接配接服務。

因為

websocket

是基于

http

協定的,是以,在

.Net

裡面還是使用

HttpListener

來偵聽。

偵聽器開始運作了以後,就可以使用

HttpListener.GetContext

,來接受用戶端的連接配接,這是個同步的方法,會阻斷目前的線程,直到有使用者連接配接上來為止。

有用戶端連接配接上來了,就可以

HttpListenerContext.Request.IsWebSocketRequest

來判斷這個

http

連接配接是不是一個合法的

WebSocket

連接配接了。

然後就

HttpListenerContext.AcceptWebSocketAsync

,這樣就能得到一個與用戶端的

WebSocket

連接配接了。

為了友善,我們在服務端的

GameMonitor

項目裡定義一個

GameConnection

類,用來集中處理使用者的連接配接。

在我們的

GameServer

類裡面添加一個

HttpListener ClientListener

成員,這活本來就該他來幹~!

因為偵聽會阻斷主線程,是以還應該有個偵聽的線程

ListenThread

還需要一個記錄連接配接的連接配接池

ConnectionPool

,這樣友善我們管理目前的全部連接配接。

在構造方法裡面對

ClientListener

ListenThread

進行初始化:

private HttpListener ClientListener;
private Thread ListenThread;
public List<GameConnection> ConnectionPool = new List<GameConnection>(1000);
……
public GameServer(MainForm monitor)
        {
            Status = 0;
            Monitor = monitor;
            LOG("GameServer建立成功");
            gGame = new Game(LOG);

            ClientListener = new HttpListener();
            ClientListener.Prefixes.Clear();
            ClientListener.Prefixes.Add("http://localhost:666/");
            ListenThread = new Thread(new ThreadStart(Listen));
        }
……
private void Listen()
        {
            ClientListener.Start();
            while (ClientListener.IsListening)
            {
                try
                {
                    HttpListenerContext context = ClientListener.GetContext();
                    HttpListenerRequest request = context.Request;
                    LOG("收到請求來自:" + request.UserHostAddress + " 的請求");
                    if (request.IsWebSocketRequest)
                    {
                        Task<HttpListenerWebSocketContext> ret = context.AcceptWebSocketAsync(null);
                        ret.Wait();
                        if (ret.Result.WebSocket != null)
                        {
                            if (ConnectionPool.Count < ConnectionPool.Capacity)
                            {
                                GameConnection connection = new GameConnection(request.UserHostAddress, ret.Result.WebSocket, LOG);
                            }
                            else
                            {
                                ret.Result.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "{\"result\":\"fail\",\"msg\":\"連接配接已滿\"}", CancellationToken.None);
                            }
                        }
                    }
                    else
                    {
                        HttpListenerResponse response = context.Response;
                        response.Close();
                    }

                }
                catch (Exception e)
                {
                    LOG(e.Message);
                }
            }
        }
           

GameConnection

類則主要包括連接配接的基本資訊以及接受資料的方法。這裡我們讓

GameConnection

連接配接後發送一個"How are you?"給用戶端。然後就開始異步接收用戶端發來的資訊,收到後LOG出來。

class GameConnection
    {
        public string IP;
        public WebSocket mSocket;
        private Action<string> LOG;

        public GameConnection(string IP,WebSocket mSocket, Action<string> LOGFUN = null)
        {
            this.IP = IP;
            this.mSocket = mSocket;
            LOG = LOGFUN==null? x => { }:LOGFUN;
            LOG("來自 "+IP+" 連接配接建立成功");
            ArraySegment<byte> segment = new ArraySegment<byte>(Encoding.UTF8.GetBytes("How are you?"));
            mSocket.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None);
            ReceiveDataAsync();
        }

        private async void ReceiveDataAsync()
        {
            while (mSocket.State == WebSocketState.Open)
            {
                WebSocketReceiveResult result;
                try
                {
                    ArraySegment<byte> receivebuff = new ArraySegment<byte>(new byte[1024]);
                    result = await mSocket.ReceiveAsync(receivebuff, CancellationToken.None);
                    string receiveStr = Encoding.UTF8.GetString(receivebuff.ToArray(), 0, result.Count);
                    LOG("收到來自 " + IP + " 的資訊:" + receiveStr);

                }
                catch
                {
                    LOG("連接配接強行中斷");
                    await mSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "{\"result\":\"fail\",\"msg\":\"伺服器斷開\"}", CancellationToken.None);
                }
            }
            LOG("連接配接已斷開");
        }
    }
           

GameServer

類的啟動和停止方法管理偵聽線程:

public void StartUp()
        {
            if (Status == 0)
            {
                gGame.Run();
                Status = 1;
                ListenThread.Start();
                LOG("GameServer啟動成功");
            }
            else
            {
                LOG("GameServer目前處于啟動狀态,請勿重複啟動");
            }
        }
        public void ShutDown()
        {
            if (Status == 1)
            {
                ClientListener.Stop();
                gGame.Stop();
                Status = 0;                
                LOG("GameServer停機成功");
            }
            else
            {
                LOG("GameServer目前處于停機狀态,無需再次停機");
            }
        }
           

好了,萬事俱備,就等用戶端連接配接上來了。

用戶端

啟動微信web開發者工具,建立一個已經注冊的小遊戲,填入AppID,路徑,名字,然後開發者工具會自動為你搭建一個“打飛機”遊戲的模闆……玩一下,看看你能得多少分。然後把所有檔案都删除,遇到無法删除的檔案夾就退出重新開機再删除。最後隻剩下三個檔案:

C#服務端的微信小遊戲——多人線上角色扮演(九)建立連接配接

然後打開game.js檔案,删除所有内容。

這個檔案是微信小遊戲預設啟動的腳本,是以,我們可以用它來調試一下我們的網絡連接配接。

在game.js檔案裡輸入代碼:

wx.connectSocket({
  url: 'ws://localhost:666/',
  method: "GET",
  success(res){
    console.log("Socket successed:")
    console.log(res)
    wx.onSocketOpen(
      (res) => {
        console.log("Socket opened:")
        console.log(res)
      }
    )
    wx.onSocketClose(
      (res) => {
        console.log("Socket closed:")
        console.log(res)
      }
    )
    wx.onSocketError((res) => {
      console.log("Socket error:")
      console.log(res)
    })
    wx.onSocketMessage((res)=>{
      console.log("got message:")
      console.log(res)
      wx.sendSocketMessage(
        {
          data:"Fine!Thank you,and you?",
          success:(res)=>{
            console.log("send msg:")
            console.log(res)
          }
        }
      );
    })
  },
  fail(res){
    console.log("Socket failed:")
    console.log(res)
  }
})
           

注意,一定要勾選這個:

C#服務端的微信小遊戲——多人線上角色扮演(九)建立連接配接

然後,我們先運作伺服器端,啟動

GameServer

再到微信web開發工具裡面,按Ctrl+B,開發工具會自動在模拟器上編譯和運作這個腳本。

運作結果如下:

用戶端:

C#服務端的微信小遊戲——多人線上角色扮演(九)建立連接配接

伺服器端:

C#服務端的微信小遊戲——多人線上角色扮演(九)建立連接配接

天啦~他們溝通得很順暢啊!

基本的溝通管道已經調通了,下一步,我們将要實作真正有意義的指令傳遞和資料下發了。

上一篇:C#服務端的微信小遊戲——多人線上角色扮演(八)

下一篇:C#服務端的微信小遊戲——多人線上角色扮演(十)

繼續閱讀