5

我目前已经构建了一个简单的 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");
    }

}
4

1 回答 1

2

问题是websocket连接。我有以下内容:

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

其中缺少 2 个关键的查询字符串参数:除了connectionDataand之外。我错误地认为这些是不需要的。tidconnectionTokentransport

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

于 2015-08-14T13:35:41.707 回答