.NET Core SignalR, проблема с выходом / переподключением сервера - PullRequest
0 голосов
/ 05 июля 2018

У меня есть концентратор SignalR, написанный в моем решении MVC, с подключением клиента Javascript из представления.

Точка подключения заключается в получении изменений для настенного экрана от сервера. Это должно произойти почти мгновенно и требует пожизненного соединения, поскольку веб-страница работает на экране без прямого доступа к компьютеру.

Пока соединение SignalR работает в течение нескольких часов, прежде чем оно выдаст ошибку.

Я получаю ошибку

Error: Connection disconnected with error 'Error: Server timeout elapsed without receiving a message form the server.'.
Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
Warning: Error from HTTP request. 0:
Error: Failed to complete negotiation with the server: Error
Error: Failed to start the connection: Error

Uncaught (in promise) Error
    at new HttpError (singlar.js:1436)
    at XMLHttpRequest.xhr.onerror (singalr.js:1583)

Код моего клиента

 let connection = new signalR.HubConnectionBuilder()
    .withUrl("/wbHub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

connection.start().then(function () {
    connection.invoke("GetAllWallboards").then(function (wallboard) {
        for (var i = 0; i < wallboard.length; i++) {
            displayWallboard(wallboard[i]);
        }
        startStreaming();
    })
})

connection.onclose(function () {
    connection.start().then(function () {
            startStreaming();
    })
})

function startStreaming() {
    connection.stream("StreamWallboards").subscribe({
        close: false,
        next: displayWallboard
    });
}

Код концентратора:

public class WallboardHub : Hub
{
    private readonly WallboardTicker _WallboardTicker;

    public WallboardHub(WallboardTicker wallboardTicker)
    {
        _WallboardTicker = wallboardTicker;
    }

    public IEnumerable<Wallboard> GetAllWallboards()
    {
        return _WallboardTicker.GetAllWallboards();
    }

    public ChannelReader<Wallboard> StreamWallboards()
    {
        return _WallboardTicker.StreamWallboards().AsChannelReader(10);
    }

    public override async Task OnConnectedAsync()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
        await base.OnDisconnectedAsync(exception);
    }
}

Вопрос 1: Правильно ли я справляюсь с переподключением? От ошибки кажется, что .onclose работает, но что он пытается только один раз? Есть ли возможность попробовать x min, прежде чем показывать ошибку?

Вопрос 2. Повторная загрузка веб-сайта приводит к тому, что соединение снова работает, есть ли вероятность обновить браузер при ошибке соединения signalR?

1 Ответ

0 голосов
/ 10 июля 2018

У меня та же проблема (Вопрос 1), и я решаю с этим:

const connection = new SignalR.HubConnectionBuilder()
    .withUrl("/hub")
    .configureLogging(SignalR.LogLevel.Information)
    .build();

connect(connection);

async function connect(conn){
    conn.start().catch( e => {
        sleep(5000);
        console.log("Reconnecting Socket");
        connect(conn);  
    }
    )
}

connection.onclose(function (e) {
            connect(connection);
    });

  async function sleep(msec) {
  return new Promise(resolve => setTimeout(resolve, msec));
}

Каждые 5 секунд пытается восстановить соединение, но я не знаю, является ли это правильным способом сделать это.

...