Signalr和WebSocketSharp在Unity3d中的应用

5
我目前已经建立了一个简单的Signalr Hub,我正在从Unity5项目中向其中推送消息。鉴于SignalR2客户端不兼容Unity5,我使用websocketsharp来拦截websocket帧。消息已成功推送到Hub中,但当我尝试在客户端上调用方法时,我收到的负载字符串只有消息标识符{"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");
    }

}

如果你在提问时能够提供相应的代码,那将会非常有帮助。 - radu-matei
1个回答

2
问题在于WebSocket连接。我有以下内容:
new WebSocket(_socket + "signalr/connect?transport=webSockets&connectionToken=" + _connectionToken)

缺少两个关键的查询字符串参数:connectionData和tid,除了connectionToken和transport。我错误地认为这些不是必需的。
希望这能帮助那些像我一样没有阅读文档的人 :)

1
你是如何获得tid的? - S.A.Parkhid
1
你是如何启用跨域的? - S.A.Parkhid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接