Unity3d 中的 Signalr 和 WebSocketSharp

Signalr & WebSocketSharp in Unity3d

我目前构建了一个简单的 Signalr Hub,我正在从 Unity5 项目向其推送消息。鉴于 SignalR2 客户端不适用于 Unity5,我正在使用 websocketsharp 来拦截 websocket 帧。消息已成功推送到集线器,但是当我尝试在客户端上调用方法时,我没有获得有效负载字符串,只有消息标识符 {"I": 0}

查看 SignalR 文档,看起来这是最后发送的,但我不知道如何才能保留它。我敢肯定它很简单,但对于我的生活我无法弄清楚。

更新

根据要求,我已经为下面的项目添加了代码...

SignalRClient.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using WebSocketSharp;

namespace Assets.Scripts
{
    class SignalRClient
    {
        private WebSocket _ws;
        private string _connectionToken;
        private Dictionary<string, UnTypedActionContainer> _actionMap;

        private readonly string _socketUrl = "http://localhost/";

        private readonly string _socket = "ws://localhost/";

        public SignalRClient()
        {
            _actionMap = new Dictionary<string, UnTypedActionContainer>();
            var webRequest = (HttpWebRequest)WebRequest.Create(_socketUrl + "/signalr/negotiate?connectionData=%5B%7B%22name%22%3A%22myHub%22%7D%5D&clientProtocol=1.3");
            var response = (HttpWebResponse)webRequest.GetResponse();

            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                var payload = sr.ReadToEnd();

                UnityEngine.Debug.Log(payload);

                _connectionToken = Uri.EscapeDataString(JsonConvert.DeserializeObject<NegotiateResponse>(payload).ConnectionToken);

                //UnityEngine.Debug.Log(_connectionToken);

            }
        }

        public void Open()
        {
            _ws = _ws == null
                ? new WebSocket(_socket + "signalr/connect?transport=webSockets&connectionToken=" + _connectionToken)
                : new WebSocket(_socket + "signalr/reconnect?transport=webSockets&connectionToken=" + _connectionToken);

            AttachAndConnect();
        }

        public void Close()
        {
            _ws.Close();
        }

        public void SendMessage(string name, string message)
        {
            //{"H":"chathub","M":"Send","A":["tester","hello"],"I":0}

            var payload = new RollerBallWrapper()
            {
                H = "myhub",
                M = "Send",
                A = new[] { name, message },
                I = 12
            };

            var wsPacket = JsonConvert.SerializeObject(payload);

            _ws.Send(wsPacket);
        }

        private void AttachAndConnect()
        {
            _ws.OnClose += _ws_OnClose;

            _ws.OnError += _ws_OnError;

            _ws.OnMessage += _ws_OnMessage;

            _ws.OnOpen += _ws_OnOpen;

            _ws.Connect();
        }

        void _ws_OnOpen(object sender, EventArgs e)
        {
            UnityEngine.Debug.Log("Opened Connection");
        }

        //
        // This seems to be retriving the last frame containing the Identifier
        void _ws_OnMessage(object sender, MessageEventArgs e)
        {
            //UnityEngine.Debug.Log(e.Data); // Returns {"I":"0"} ????
        }

        void _ws_OnError(object sender, WebSocketSharp.ErrorEventArgs e)
        {
            UnityEngine.Debug.Log(e.Message);
        }

        void _ws_OnClose(object sender, CloseEventArgs e)
        {
            UnityEngine.Debug.Log(e.Reason + " Code: " + e.Code + " WasClean: " + e.WasClean);
        }

        public void On<T>(string method, Action<T> callback) where T : class
        {
            _actionMap.Add(method, new UnTypedActionContainer
            {
                Action = new Action<object>(x =>
                {
                    callback(x as T);
                }),
                ActionType = typeof(T)
            });
        }
    }

    internal class UnTypedActionContainer
    {
        public Action<object> Action { get; set; }
        public Type ActionType { get; set; }
    }

    class MessageWrapper
    {
        public string C { get; set; }

        public RollerBallWrapper[] M { get; set; }
    }

    class RollerBallWrapper
    {
        public string H { get; set; }

        public string M { get; set; }

        public string[] A { get; set; }

        public int I { get; set; }
    }
}

MyHub.cs

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;

public class MyHub : Hub
{
    public void Send(string name, string message)
    {
        var myConn = Context.ConnectionId;

        Clients.All.broadcastMessage("John", "Hello");
    }

}

问题出在 websocket 连接上。我有以下内容:

new WebSocket(_socket + "signalr/connect?transport=webSockets&connectionToken=" + _connectionToken)

缺少 2 个关键查询字符串参数:connectionDatatid,以及 connectionTokentransport。我错误地认为不需要这些。

我希望这对像我一样没有阅读文档的人有所帮助:)