SignalR角度在获得字典对象时断开连接

问题描述 投票:1回答:1

使用asp.net core 2.2和angular 7,(asp.netcore:signalr 1.1.0 + angular:“ @ aspnet / signalr”:“ ^ 1.1.4”)

直到我尝试将字典发送给angular之前,它都工作正常。当它尝试发送字典时,它会断开连接。

Utils.js:209 [2019-12-29T11:09:11.959Z] Information: WebSocket connected to ws://localhost:64408/chat?id=6d-C7eu1X-Pv8t4-RwdbYg. 
Utils.js:209 [2019-12-29T11:09:12.132Z] Information: Connection disconnected.

这些是我的代码:

InMemoryChatRoomService类:

 public class InMemoryChatRoomService : IChatRoomService
    {
        private readonly Dictionary<Guid, ChatRoom> _roomInfo = new Dictionary<Guid, ChatRoom>();

        public Task<IReadOnlyDictionary<Guid, ChatRoom>> GetAllRooms()
        { 
            return Task.FromResult(_roomInfo as IReadOnlyDictionary<Guid, ChatRoom>);
        } 

    }

IChatroomService:

using SignalR.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SignalR
{
    public interface IChatRoomService
    {

        Task<IReadOnlyDictionary<Guid, ChatRoom>> GetAllRooms(); 
    }
}

ChatHub类:

using Microsoft.AspNetCore.SignalR;
using SignalR.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SignalR
{
    public class ChatHub : Hub
    {
        private readonly IChatRoomService _chatRoomService;
        public ChatHub(IChatRoomService ChatRoomService)
        {
            _chatRoomService = ChatRoomService;

        }
        public override async Task OnConnectedAsync()
        { 
            await Clients.Caller.SendAsync("ActiveRooms", await _chatRoomService.GetAllRooms()); 
            await base.OnConnectedAsync();
        }
    }
}

角度:

import { Component, OnInit } from '@angular/core';
import * as signalR from "@aspnet/signalr";
import { HttpClient } from "@angular/common/http";
import { MessagePacket } from './MessagePacket.model';
import { ChatService } from './chat.service';
import { ChatRoom } from './ChatRoom.model';

@Component({
    selector: 'app-chat',
    templateUrl: './chat.component.html',
    styleUrls: ['./chat.component.scss']
})
export class ChatComponent implements OnInit {

    constructor(private http: HttpClient, private chatService: ChatService) { }

    private hub: signalR.HubConnection;
    rooms = [ ];
    messagePackets: MessagePacket[] = [];
    isConnected = false;
    connectionAttempts = 0;
    ipAddress = '';
    typedMessage = '';
    userChatName = 'salar';//todo: load user data

    ngOnInit() { 
        //build connection
        this.hub = new signalR.HubConnectionBuilder()
            .withUrl('http://localhost:64408/chat')
            .build();

        //start connection
        this.startConnection();


        this.hub.on('ActiveRooms', (rooms ) => {
            this.ActiveRooms(rooms)
        });


        //on disconnect
        this.hub.onclose(h => {
            this.isConnected = false;
             setTimeout(x => this.startConnection(), 3000)
        });
    }

    startConnection() {
        this.connectionAttempts++;
        console.log('Connecting!')
        this.hub
            .start()
            .then(() => {
                this.connectionAttempts = 0;
                this.isConnected = true;
                console.log('Connection started!');
                console.log('Getting all rooms');
               // this.hub.invoke("ActiveRooms");

            })
            .catch(err => {
                if (this.connectionAttempts < 10) {
                    console.log(this.connectionAttempts + ' try for connection')
                     setTimeout(x => this.startConnection(), 3000)
                } else {
                    console.log('Error while establishing connection. changed mode to manual')
                }
            });
    }


    ActiveRooms(rooms ) {
        var x = '';
       // this.rooms = rooms;
    }


}

当我跟踪时,它尝试发送回字典,然后,signaler断开连接并尝试再次连接。如果它不是字典并且像字符串或其他对象,则可以正常工作。

UPDATE:

当我将字典的GUID类型更改为STRING时,它会变好:

 public Task<IReadOnlyDictionary<string, ChatRoom>> GetAllRooms()
        {
            //type guid gives error so needs to be converted to string
            Dictionary<string, ChatRoom> result = new Dictionary<string, ChatRoom>();
            foreach (var room in _roomInfo)
            {
                result.Add(room.Key.ToString(), room.Value);
            }
            return Task.FromResult(result as IReadOnlyDictionary<string, ChatRoom>);
        } 

GUID有问题。

angular dictionary asp.net-core signalr disconnect
1个回答
0
投票

SignalR在要序列化/反序列化GUID时遇到问题,它必须在C#端和JS端都可以工作。 GUID有点棘手。它是一个结构,而不是一个类。它具有二进制表示形式和字符串表示形式。

我发现了这个问题:https://github.com/aspnet/SignalR/issues/1043

从问题描述来看,这似乎是库的限制,没有计划对其进行修复。实际上,这是JavaScript本身的局限性。它没有内置的GUID类型。该库不会对此情况发出任何警告。

作为一种解决方法,您可以像在您发布的示例中那样输入字符串,也可以为GUID创建自己的类型,但仅使用内置的JS原始类型来定义它。

© www.soinside.com 2019 - 2024. All rights reserved.