каково время жизни потока для клиента в сценариях остановки / запуска хаб-соединения, и если сервер явно прерывает соединение (из-за тайм-аутов access_token и, следовательно, из-за того, что клиент обновляет свое соединение).
Когда соединение разорвано (либо из-за того, что stop
вызывается на клиенте или сервере, прерывающем соединение), метод error
вашего подписчика будет вызван с ошибкой, указывающей, что поток имеетбыло прервано, потому что соединение было разорвано.В общем случае вы должны обработать метод error
и считать его терминальным событием (т. Е. Поток никогда не даст дополнительных объектов).На сервере токен Context.ConnectionAborted
будет запущен, если соединение разорвано (любой стороной), и вы можете прекратить запись в свой поток.
Если вы уже используете RxJS, я настоятельно рекомендуюсоздание небольшой оболочки для преобразования объекта, который вы возвращаете из SignalR, в правильный RxJS Observable
.Объект, который мы возвращаем, не является на самом деле и Observable
, но он имеет все те же основные методы (метод subscribe
, который принимает объект с помощью методов complete
, next
и error
), поэтому это должно быть тривиально, чтобы обернуть его.
Я попытался вызвать dispose в потоке, что нормально, если концентратор подключен, но он ошибается, если соединение находится в отключенном состоянии.Мне интересно, если это ошибка или нет.
Да, это, вероятно, ошибка.Мы не должны бросать, если вы утилизируете после отключения концентратора.Можете ли вы подать это на https://github.com/aspnet/SignalR?Чтобы обойти это, вы можете довольно безопасно просто try...catch
сообщить об ошибке и устранить ее (или, может быть, зарегистрировать ее, если вы параноик).
Можно ли просто удалить подписку streams затем и заново создатьпо мере необходимости, или эта утечка будет каким-либо образом?
Вы должны всегда dispose
подписку.Если вы просто delete
это сделаете, мы не сможем узнать, что с вами покончено, и мы никогда не скажем серверу остановиться.Если вы звоните dispose
(и подключены), мы отправляем сообщение на сервер, «отменяя» поток.В ASP.NET Core 2.1 мы не предоставляем эту отмену вам, но мы прекращаем чтение с ChannelReader
.В ASP.NET Core 2.2 мы разрешаем вам принять CancellationToken
в вашем методе Hub, а метод dispose
на клиенте вызовет этот токен в методе Hub.Я настоятельно рекомендую вам попробовать последний предварительный просмотр ASP.NET Core 2.2 и использовать CancellationToken
в методе Hub для остановки потока:
public ChannelReader<object> MyStreamingMethod(..., CancellationToken cancellationToken) {
// pass 'cancellationToken' over to whatever process is writing to the channel
// and stop writing when the token is triggered
}
Примечание. Если вы сделаете это, вы неДля отслеживания Context.ConnectionAborted
токен, передаваемый в ваш метод Hub, будет охватывать все случаи отмены.
В связанной заметке вы должны всегда использовать Channel.CreateBounded<T>(size)
для создания своего канала,Если вы используете неограниченный канал, утечка памяти будет намного проще, так как писатель может продолжать писать бесконечно.Если вы используете ограниченный канал, устройство записи будет остановлено (WriteAsync
и WaitToWriteAsync
заблокируют), если в канале будет size
непрочитанных элементов (потому что, например, клиент отключился и мыперестал читать).