Signalr .net клиент

Итак, я пытаюсь подключиться к службе на С#, я не контролирую эту службу и ничего не могу там изменить, и у меня нет никакой документации, которая могла бы помочь :(

так что я пытаюсь сделать, это изменить этот клиент JavaScript SignalR на .net (но не все)

    $(document).ready(function () {

        //URL of the queues api
        var queueApi = "/CCMWa/api/v1/queues/";

        //SignalR connection
        $.connection.hub.logging = true;
        var myHub = $.connection.queueStatistics;

        //Wire event handlers
        myHub.client.onQueueNowDataUpdate = function (data) {
            //alert(data);
            var data = JSON.stringify(data);
            $('#messages').append('<li>Server: Received onQueueNowDataUpdate</li>');
            $('#getNowResults').text(data);
        };

        //Wire event handlers
        myHub.client.onQueueConversationUpdate = function (data) {
            //alert(data);
            var data = JSON.stringify(data);
            $('#messages').append('<li>Server: Received onQueueConversationUpdate</li>');
            $('#getConversationResults').text(data);
        };

        //Wire event handlers
        myHub.client.connected = function () {
            $('#messages').append('<li>Server: Says we are Connected</li>');                
        };

        //Wire event handlers
        myHub.client.reconnected = function () {
            $('#messages').append('<li>Server: Says we are Reconnected</li>');
        };

        //Start
        $.connection.hub.start()
                        .done(function () {
                            logMessage("Client: Connection Started");
                            //myHub.server.joinFoo()
                            //     .done(function () {
                            //         logMessage("Client: Sent Join to Server");
                            //     })
                        })
                        .fail(function () {
                            logMessage("Client: Could not connect to server");
                        });

        $("#startNow").click(function () {
            var id = $("#queueNowId").val();

            myHub.server.startQueueStateMonitor(id)
               .done(function () {
                   $('#messages').append('<li>Client: addMonitor for ' + id + '</li>');
               })
               .fail(function () {
                   $('#messages').append('<li>Client: failed to send addMonitor</li>');
               });

        });

        function logMessage(message)
        {
            $('#messages').append(message);
        }

        $("#stopNow").click(function () {
            var id = $("#queueNowId").val();

            myHub.server.stopQueueStateMonitor(id)
               .done(function () {
                   $('#messages').append('<li>Client: removeMonitor for ' + id + '</li>');
               })
               .fail(function () {
                   $('#messages').append('<li>Client: failed to send removeMonitor</li>');
               });
        });

        $("#getAll").click(function () {
            var uri = queueApi;
            //alert(uri);
            $.get(uri,
                function (items) {
                    data = JSON.stringify(items);
                    $("#getAllResults").text(data);
                });                
        });

        $("#getDetails").click(function () {
            var id = $("#queueDetailsId").val();
            var uri = queueApi + id;
            //alert(uri);
            $.get(uri,
                function (items) {
                    data = JSON.stringify(items);
                    $('#getDetailsResults').text(data);
                });
        });           

        $("#getNow").click(function () {
            var id = $("#queueNowId").val();
            var uri = queueApi + id + "/now";
            //alert(uri);
            $.get(uri,
                function (items) {
                    data = JSON.stringify(items);
                    $('#getNowResults').text(data);
                });
        });


        $("#startConversationMonitor").click(function () {
            var id = $("#queueConversationsId").val();

            myHub.server.startQueueConversationMonitor(id)
               .done(function () {
                   $('#messages').append('<li>Client: addMonitor for ' + id + '</li>');
               })
               .fail(function () {
                   $('#messages').append('<li>Client: failed to send addMonitor</li>');
               });
        });


        $("#stopConversationMonitor").click(function () {
            var id = $("#queueConversationsId").val();

            myHub.server.stopQueueConversationMonitor(id)
               .done(function () {
                   $('#messages').append('<li>Client: removeMonitor for ' + id + '</li>');
               })
               .fail(function () {
                   $('#messages').append('<li>Client: failed to send removeMonitor</li>');
               });
        });

        $("#getConversations").click(function () {
            var id = $("#queueConversationsId").val();
            var uri = queueApi + id + "/conversations";
            //alert(uri);
            $.get(uri,
                function (items) {
                    data = JSON.stringify(items);
                    $('#getConversationResults').text(data);
                });
        });
    });       

Вот что у меня сейчас есть в С#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNet.SignalR.Client.Hubs;

namespace ConsoleApplication3
{
class Program
{
    static void Main(string[] args)
    {
        //Set connection
        var connection = new HubConnection("http://servername/CCMWa/");
        connection.TraceLevel = TraceLevels.All;
        connection.TraceWriter = Console.Out;

        //Make proxy to hub based on hub name on server
        var myHub = connection.CreateHubProxy("queueStatistics");

        //Start connection


        connection.Start().ContinueWith(task => {
            if (task.IsFaulted) {
                Console.WriteLine("There was an error opening the connection:{0}",
                                  task.Exception.GetBaseException());
            } else {
                Console.WriteLine("Connected");
            }

        }).Wait();

        myHub.Invoke<string>("startQueueStateMonitor", "445cb4e7-88a7-47d4-bb13-e8b40854f4a5").ContinueWith(task =>
        {
            if (task.IsFaulted) {
                Console.WriteLine("There was an error calling send: {0}",
                                  task.Exception.GetBaseException());
            } else {
                Console.WriteLine("hello");     
                Console.WriteLine(task.Result);                  
            }
        });


        myHub.On("connected", () => Console.WriteLine(" server said connected"));

        myHub.On<string>("onQueueNowDataUpdate", data => { Console.WriteLine(data); });

        //myHub.On<string>("onQueueConversationUpdate", data => { Console.WriteLine(data); });


        Console.Read();
        connection.Stop();
    }
    }
}

и вот его вывод

            08:10:06.4207699 - null - ChangeState(Disconnected, Connecting)                 

            08:10:06.7977915 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - SSE: GET http://servername/CCMWa/signalr/connect?transport=serverSentEvents&connectionToken=n6c1mQ6E22kyyqrALVJ2LK2nlWqKQbFZmJOLs9flk75jhvbwPPddp5wGcBMg_9VGeXtWLlqmjETWUaT_de8KLiODqxZG3ZAa6KzHqM9Ik4cuS0CuWnz8YspN79wPsF3l0&connectionData=[{"Name":"queueStatistics"}]                 

            08:10:06.8617951 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - ChangeState(Connecting, Connected) Connected              

            08:10:06.8667954 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - SSE: OnMessage(Data: initialized)                 
            08:10:07.0518060 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - OnMessage({"I":"0"}) hello                
            08:10:07.1168097 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - SSE: OnMessage(Data: {"C":"Gg,0|Ix,1|Iy,0|Iz,0","M":[{"H":"queueStatistics","M":"connected","A":[]}]})  server said connected                 08:10:07.1328106 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - SSE: OnMessage(Data: {"C":"Gg,0|Ix,1|Iy,1|Iz,0|Hf,13A2","G":"JbB1ER_V5dMWm0Cxe5LFQluULoB69DHmULrH6WM_nM2Dbsk-y-qGne7GwpaUSUlSfdS1KNUjuVgU-Femd 3IucV56Iw545IKDvlxNXL7pmdcGtvZbAIjMKIjXbEdTLSMAkxGGJZDhr4nD4KWzpHMQtA2","M":[]})               08:10:07.1338107 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - SSE: OnMessage(Data: {"C":"Gg,0|Ix,2|Iy,1|Iz,0|Hf,13A2","M":[{"H":"queueStatistics","M":"onQueueNowDataUpdate","A":[{"configData":{"Id":"445cb 4e7-88a7-47d4-bb13-e8b40854f4a5","Name":"Dutch","Reporting":"P503","MediaType":0,"MediaServer":null,"MediaServerId":"00000000-0000-0000-0000-000000000000","NowStatisticsUrl":null,"StatisticsHubName":" queueStatistics","Links":[],"Url":null},"Status":"ACD","LongestWaiting":0.0,"Acd":0,"NonAcd":0,"Out":0,"Unavailable":1,"Offered":3,"Handled":3,"Abandoned":0,"Interflow":0,"Requeue":0,"ServiceLevel":10 0,"AgentsIdle":2,"ItemsWaiting":0,"QueueOpen":false,"AgentsLoggedIn":0,"AgentsAvailable":2,"EstimatedWaitTime":0.0,"AverageHandlingTime":0,"DetailsUrl":null}]}]})               

            08:10:07.1878138 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - OnError(Newtonsoft.Json.JsonReaderException: Error reading string. Unexpected token: StartObject. Path ''.    at Newtonsoft.Json.JsonReader.ReadAsStringInternal()    at Newtonsoft.Json.Linq.JTokenReader.ReadAsString()    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)    at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)    at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)    at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)    at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer)    at Microsoft.AspNet.SignalR.Client.Hubs.HubProxyExtensions.Convert[T](JToken obj, JsonSerializer serializer)    at Microsoft.AspNet.SignalR.Client.Hubs.HubProxyExtensions.<>c__DisplayClass6`1.<On>b__4(IList`1 args)    at Microsoft.AspNet.SignalR.Client.Hubs.Subscription.OnReceived(IList`1 data)    at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.InvokeEvent(String eventName, IList`1 args)    at Microsoft.AspNet.SignalR.Client.Hubs.HubConnection.OnMessageReceived(JToken message)    at Microsoft.AspNet.SignalR.Client.Connection.Microsoft.AspNet.SignalR.Client.IConnection.OnReceived(JToken message)    at Microsoft.AspNet.SignalR.Client.Transports.TransportHelper.ProcessResponse(IConnection connection, String response, Boolean& timedOut, Boolean& disconnected))              

            08:10:08.0928655 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - SSE: OnMessage(Data: {"C":"Gg,0|Ix,2|Iy,1|Iz,0|Hf,13A3","M":[{"H":"queueStatistics","M":"onQueueNowDataUpdate","A":[{"configData":{"Id":"445cb 4e7-88a7-47d4-bb13-e8b40854f4a5","Name":"Dutch","Reporting":"P503","MediaType":0,"MediaServer":null,"MediaServerId":"00000000-0000-0000-0000-000000000000","NowStatisticsUrl":null,"StatisticsHubName":" queueStatistics","Links":[],"Url":null},"Status":"ACD","LongestWaiting":0.0,"Acd":0,"NonAcd":0,"Out":0,"Unavailable":1,"Offered":3,"Handled":3,"Abandoned":0,"Interflow":0,"Requeue":0,"ServiceLevel":10 0,"AgentsIdle":2,"ItemsWaiting":0,"QueueOpen":false,"AgentsLoggedIn":0,"AgentsAvailable":2,"EstimatedWaitTime":0.0,"AverageHandlingTime":0,"DetailsUrl":null}]}]})               

            08:10:08.1308677 - 66fd7caa-b3f8-4297-9c83-5a2dd5c9e72e - OnError(Newtonsoft.Json.JsonReaderException: Error reading string. Unexpected token: StartObject. Path ''.    at Newtonsoft.Json.JsonReader.ReadAsStringInternal()    at Newtonsoft.Json.Linq.JTokenReader.ReadAsString()    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)    at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)    at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)    at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)    at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer)    at Microsoft.AspNet.SignalR.Client.Hubs.HubProxyExtensions.Convert[T](JToken obj, JsonSerializer serializer)    at Microsoft.AspNet.SignalR.Client.Hubs.HubProxyExtensions.<>c__DisplayClass6`1.<On>b__4(IList`1 args)    at Microsoft.AspNet.SignalR.Client.Hubs.Subscription.OnReceived(IList`1 data)    at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.InvokeEvent(String eventName, IList`1 args)    at Microsoft.AspNet.SignalR.Client.Hubs.HubConnection.OnMessageReceived(JToken message)    at Microsoft.AspNet.SignalR.Client.Connection.Microsoft.AspNet.SignalR.Client.IConnection.OnReceived(JToken message)    at Microsoft.AspNet.SignalR.Client.Transports.TransportHelper.ProcessResponse(IConnection connection, String response, Boolean& timedOut, Boolean& disconnected))` 

Может ли кто-нибудь предложить какое-либо руководство к тому, что я делаю неправильно здесь


person Andrew Jackson    schedule 19.06.2015    source источник
comment
Я откатил ваше массовое изменение вопроса. На этот вопрос уже дан ответ, поэтому он должен остаться для справки для других пользователей. Если у вас есть новый вопрос, вы должны задать новый отдельный вопрос - вы всегда можете сослаться на него там.   -  person Jon Egerton    schedule 19.06.2015


Ответы (1)


Не на 100% в этом, не запуская его самостоятельно, но:

Я думаю, что проблема в вашей строке отладки:

myHub.On<string>("onQueueNowDataUpdate", data => { Console.WriteLine(data); });

Эта строка обрабатывает входящее сообщение как строку, за исключением того, что данные не являются строкой, поскольку это сериализованный объект.

т.е. то, что находится в данных, является частью, которая выглядит следующим образом в трассировке (я думаю, что M обозначает тело сообщения):

 "M": [
            {
                "H": "queueStatistics",
                "M": "onQueueNowDataUpdate",
                "A": [
                    {
                        "configData": {

Десериализатор Json хочет что-то вроде

 "M": "Foobar"

На самом деле вам нужно объявление класса, которое соответствует входящему сообщению (учтите, что это, вероятно, то, что вы собираетесь написать дальше).

Обновление для создания классов:

Самый простой способ создать класс из Json — позволить кому-то другому сделать это за вас. Если вы вставите сообщение (не обращая внимания на часть "M:[") в json2csharp.com:

            {
                "H": "queueStatistics",
                "M": "onQueueNowDataUpdate",
                "A": [
                    {
                        "configData": {
                            "Id": "445cb 4e7-88a7-47d4-bb13-e8b40854f4a5",
                            "Name": "Dutch",
                            "Reporting": "P503",
                            "MediaType": 0,
                            "MediaServer": null,
                            "MediaServerId": "00000000-0000-0000-0000-000000000000",
                            "NowStatisticsUrl": null,
                            "StatisticsHubName": " queueStatistics",
                            "Links": [

                            ],
                            "Url": null
                        },
                        "Status": "ACD",
                        "LongestWaiting": 0.0,
                        "Acd": 0,
                        "NonAcd": 0,
                        "Out": 0,
                        "Unavailable": 1,
                        "Offered": 3,
                        "Handled": 3,
                        "Abandoned": 0,
                        "Interflow": 0,
                        "Requeue": 0,
                        "ServiceLevel": 100,
                        "AgentsIdle": 2,
                        "ItemsWaiting": 0,
                        "QueueOpen": false,
                        "AgentsLoggedIn": 0,
                        "AgentsAvailable": 2,
                        "EstimatedWaitTime": 0.0,
                        "AverageHandlingTime": 0,
                        "DetailsUrl": null
                    }
                ]
            }

Ты получаешь:

public class ConfigData
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Reporting { get; set; }
    public int MediaType { get; set; }
    public object MediaServer { get; set; }
    public string MediaServerId { get; set; }
    public object NowStatisticsUrl { get; set; }
    public string StatisticsHubName { get; set; }
    public List<object> Links { get; set; }
    public object Url { get; set; }
}

public class A
{
    public ConfigData configData { get; set; }
    public string Status { get; set; }
    public double LongestWaiting { get; set; }
    public int Acd { get; set; }
    public int NonAcd { get; set; }
    public int Out { get; set; }
    public int Unavailable { get; set; }
    public int Offered { get; set; }
    public int Handled { get; set; }
    public int Abandoned { get; set; }
    public int Interflow { get; set; }
    public int Requeue { get; set; }
    public int ServiceLevel { get; set; }
    public int AgentsIdle { get; set; }
    public int ItemsWaiting { get; set; }
    public bool QueueOpen { get; set; }
    public int AgentsLoggedIn { get; set; }
    public int AgentsAvailable { get; set; }
    public double EstimatedWaitTime { get; set; }
    public int AverageHandlingTime { get; set; }
    public object DetailsUrl { get; set; }
}

public class RootObject
{
    public string H { get; set; }
    public string M { get; set; }
    public List<A> A { get; set; }
}

Вы должны изменить имя RootObject на что-то более понятное для вас. Также обратите внимание, что, очевидно, это знает только о свойствах, которые находятся в исходном Json, поэтому вы должны сделать это с самой сложной версией сообщения, которое вы будете получать, чтобы вы могли ничего не пропустить.

Затем вы можете получить экземпляр класса с помощью (почти так же, как с версией JS):

myHub.On<RootObject>("onQueueNowDataUpdate", data => { <<Do something with RootData instance here>> });
person Jon Egerton    schedule 19.06.2015
comment
Не работая в С# очень долго, я не уверен, как сделать объявление класса для этого, не могли бы вы указать мне какие-то ресурсы, которые объясняют это для меня, пожалуйста? - person Andrew Jackson; 19.06.2015
comment
Спасибо, я немного погуглил и нашел тот же сайт :) Это, кажется, решило мою проблему. Я просто тестирую это сейчас И спасибо, что уделили мне время, чтобы помочь мне, я очень ценю это - person Andrew Jackson; 19.06.2015
comment
Вы знаете, как мне получить доступ к данным внутри моего класса? - person Andrew Jackson; 19.06.2015