Blazor Server შენს კომპონენტებს სერვერზე უშვებს და UI-ის განახლებებს ბრაუზერს SignalR კავშირით უგზავნის: ყოველი გახსნილი ჩანართი ცოცხალი circuit-ია, რომელიც მდგომარეობას სერვერის მეხსიერებაში ინახავს, ყოველი დაწკაპუნება ორმხრივი მოგზაურობაა ქსელში, და სერვერის მეხსიერება ერთდროული მომხმარებლების რაოდენობასთან ერთად იზრდება და არა მოთხოვნებთან ერთად. Blazor WebAssembly .NET runtime-სა და შენს აპლიკაციას ბრაუზერში ჩამოტვირთავს და იქ უშვებს: სერვერი მხოლოდ სტატიკურ ფაილებსა და API-ს ემსახურება, მაგრამ პირველი ვიზიტი რამდენიმემეგაბაიტიან ჩამოტვირთვად ჯდება და კლიენტში ვერაფერი იქნება საიდუმლო. .NET 8-იდან მთელი აპლიკაციისთვის ერთის არჩევა აღარ გიწევს - Blazor Web App მოდელი გვერდებს ნაგულისხმევად სერვერზე სტატიკურად არენდერებს და თითოეულ კომპონენტს აძლევს უფლებას, აირჩიოს Server, WebAssembly ან Auto ინტერაქტიულობა.
ჰოსტინგისთვის კითხვა მარტივია: რამდენი ადამიანი იქნება ერთდროულად დაკავშირებული, რამდენად შორს არიან ისინი სერვერიდან და შეუძლია თუ არა სერვერს ყველა მათგანის დამახსოვრება? ეს პოსტი თითოეულ ამ კითხვას რიცხვებით პასუხობს.
რენდერის რეჟიმები ერთ ცხრილში#
Blazor Web App (ნაგულისხმევი შაბლონი .NET 8-იდან) კომპონენტის რენდერის ოთხ გზას უჭერს მხარს:
| რენდერის რეჟიმი | სად მუშაობს კოდი | ინტერაქტიული | სერვერის ხარჯი ვიზიტორზე |
|---|---|---|---|
| სტატიკური სერვერული (SSR) | სერვერზე, ყოველ მოთხოვნაზე | არა (მხოლოდ ფორმები და ბმულები) | ჩვეულებრივი HTTP მოთხოვნა |
InteractiveServer | სერვერზე, circuit-ში | კი | ცოცხალი circuit მთელი ვიზიტის განმავლობაში |
InteractiveWebAssembly | ბრაუზერში | კი | სტატიკური ფაილები, შემდეგ API გამოძახებები |
InteractiveAuto | ჯერ სერვერზე, მერე ბრაუზერში | კი | circuit, სანამ runtime ქეშში არ მოხვდება |
სტატიკური SSR ადვილად შეუმჩნეველი რჩება და ხშირად სწორედ ის არის სწორი პასუხი. გვერდს, რომელიც მონაცემებს აჩვენებს და ფორმას აგზავნის, ინტერაქტიულობა საერთოდ არ სჭირდება; ის Razor Page-ივით რენდერდება და პასუხის გაგზავნის შემდეგ სერვერს არაფერი უჯდება. Enhanced navigation სტატიკურ გვერდებს შორის ბმულებს single-page აპლიკაციის შეგრძნებას აძლევს, ხოლო [StreamRendering] ნელ გვერდს საშუალებას აძლევს, ჯერ layout გაგზავნოს, მონაცემები კი მაშინ, როცა მოვა.
ინტერაქტიულობა კომპონენტზე ან მთელ აპლიკაციაზე ყენდება:
builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .AddInteractiveWebAssemblyComponents();app.MapRazorComponents<App>() .AddInteractiveServerRenderMode() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(Client._Imports).Assembly);შემდეგ კომპონენტი აცხადებს @rendermode InteractiveServer (ან რომელიმე სხვას), და ინტერაქტიულობის ფასს მხოლოდ ეს კომპონენტი და მისი შვილები იხდიან. ძველი დამოუკიდებელი Blazor Server და "ASP.NET Core hosted" WebAssembly შაბლონები .NET 8-იდან მოყოლებული აღარ არსებობს; მათზე აგებული არსებული აპლიკაციები კვლავ მუშაობს.
როგორ მუშაობს Blazor Server#
როცა ინტერაქტიული სერვერული კომპონენტის მქონე გვერდი იტვირთება, ბრაუზერი სერვერთან SignalR კავშირს ხსნის, სასურველია WebSocket-ებით. სერვერი ქმნის circuit-ს: გვერდზე არსებული ყოველი ინტერაქტიული კომპონენტის ეგზემპლარს, მათ მდგომარეობას, render tree-ს და scoped dependency injection კონტეინერს. ამის შემდეგ:
- მომხმარებელი ღილაკს აწკაპუნებს. ბრაუზერი მოვლენას კავშირით აგზავნის.
- სერვერი უშვებს მოვლენის დამმუშავებელს, თავიდან არენდერებს შეხებულ კომპონენტებს და ითვლის სხვაობას ბოლო რენდერთან.
- სერვერი სხვაობას უკან აგზავნის, ბრაუზერი კი DOM-ს ასწორებს.
სწორედ ამიტომ ჰგავს Blazor Server-ზე წერა დესკტოპ აპლიკაციის წერას: კოდს მონაცემთა ბაზის პირდაპირ გამოძახება შეუძლია, ასაშენებელი API ფენა არ არსებობს და მგრძნობიარე არაფერი არასოდეს აღწევს ბრაუზერამდე. ამიტომვეა მისი ხარჯები ჩვეულებრივი ვებ აპლიკაციისგან განსხვავებული. circuit მანამდე ცოცხლობს, სანამ ჩანართი ღიაა, აკეთებს რამეს მომხმარებელი თუ არა, და მასში არსებული scoped სერვისებიც - EF Core-ის DbContext-ის ჩათვლით, თუ მას პირდაპირ inject-ავ - ზუსტად იმდენ ხანს ცოცხლობს.
მეხსიერება და CPU მომხმარებელზე#
Microsoft-ის საკუთარი რეკომენდაცია ძალიან მარტივი აპლიკაციისთვის მინიმუმად დაახლოებით 250 KB სერვერის მეხსიერებას ასახელებს თითო დაკავშირებულ მომხმარებელზე. რეალური აპლიკაციები გაცილებით მეტს ინახავს: ყოველი კომპონენტის ველებს, ნებისმიერ მონაცემს, რომელიც მათში ჩატვირთე, ათასობით სტრიქონიან grid-ებს და scoped სერვისებს. circuit, რომელიც 5,000-სტრიქონიან grid-ს თავისი მონაცემებით ინახავს, მეგაბაიტებით იზომება, და მას მთელი ვიზიტის განმავლობაში ინახავს.
ზომის შეფასების უხეში გზა: გაზომე ერთი circuit. გახსენი აპლიკაცია ერთ ჩანართში, დაიმახსოვრე მეხსიერების გრაფიკი, გახსენი კიდევ ოცი ჩანართი ყველაზე მძიმე გვერდზე და ზრდა ოცზე გაყავი. შემდეგ გაამრავლე იმ ადამიანების რაოდენობაზე, რომლებსაც ელი, რომ აპლიკაცია ერთსა და იმავე მომენტში ექნებათ გახსნილი - არა დღეში, არამედ ერთდროულად.
| ერთდროული მომხმარებლები | მსუბუქი გვერდები (თითო დაახლოებით 0.5 MB) | მძიმე გვერდები (თითო დაახლოებით 5 MB) |
|---|---|---|
| 20 | 10 MB | 100 MB |
| 200 | 100 MB | 1 GB |
| 1,000 | 500 MB | 5 GB |
ეს მომხმარებელზე მოსული რიცხვები საილუსტრაციოა და შენს აპლიკაციაზე გაზომილი არ არის; მთავარი ფორმაა. Blazor Server აპლიკაცია, რომელიც მომხმარებლებით სავსე ოფისისთვის კარგად მუშაობს, შეიძლება შეუფერებელი იყოს საჯარო საიტისთვის, სადაც ათასობით ადამიანი შეიძლება ერთდროულად მოვიდეს. .NET-ის მეხსიერება და garbage collection პროცესის საბაზო მეხსიერებას განიხილავს, რომელიც circuit-ებს ემატება.
circuit-ის პარამეტრები, რომლებიც ამას ზღუდავს:
CircuitOptions პარამეტრი | ნაგულისხმევი | რას აკეთებს |
|---|---|---|
DisconnectedCircuitRetentionPeriod | 3 წუთი | რამდენ ხანს ინახება გაწყვეტილი circuit ხელახლა დასაკავშირებლად |
DisconnectedCircuitMaxRetained | 100 | რამდენი გაწყვეტილი circuit ინახება ერთდროულად |
JSInteropDefaultCallTimeout | 1 წუთი | JavaScript-ის გამოძახებების timeout |
MaxBufferedUnacknowledgedRenderBatches | 10 | ნელი კლიენტისთვის რიგში ჩამდგარი render batch-ები |
DetailedErrors | false | გამონაკლისის დეტალების ბრაუზერში გაგზავნა - მხოლოდ development-ისთვის |
როცა შეგიძლია, მონაცემები კომპონენტების გარეთ შეინახე: ჩატვირთე შედეგების ერთი გვერდი და არა მთელი ცხრილი. გრძელი სიებისთვის გამოიყენე Virtualize, რომ მხოლოდ ხილული სტრიქონები დარენდერდეს. შექმენი DbContext ყოველ ოპერაციაზე IDbContextFactory<T>-ით, ნაცვლად იმისა, რომ ერთი circuit-ის მთელი სიცოცხლისთვის inject-ო.
CPU ჩვეულებრივ ნაკლები პრობლემაა, რადგან მოვლენების უმეტესობა იაფია. მას მნიშვნელობა აქვს, როცა ბევრი მომხმარებელი ერთდროულად ძვირ რენდერებს იწვევს - dashboard, რომელიც ტაიმერით ყოველი დაკავშირებული მომხმარებლისთვის თავიდან რენდერდება, დატვირთვაა, რომელიც აუდიტორიასთან ერთად იზრდება მაშინაც, როცა არავინ არაფერს ეხება.
დაყოვნება და კავშირი#
Blazor Server-ში ყოველი ურთიერთქმედება ქსელს ელოდება. მომხმარებელსა და სერვერს შორის 20 ms-ზე ღილაკი მყისიერად რეაგირებს. 150 ms-ზე ველში წერა, რომელიც ყოველ კლავიშზე თავიდან რენდერდება, წებოვნად იგრძნობა, ხოლო drag-and-drop გაფუჭებულს ჰგავს. თუ შენი მომხმარებლები სერვერისგან სხვა კონტინენტზე არიან, Server რეჟიმზე გადაწყვეტილების მიღებამდე იქიდან გატესტე. დაყოვნება, jitter და პაკეტების დაკარგვა ხსნის, რას ნიშნავს ეს რიცხვები პრაქტიკაში.
კავშირმა ასევე უნდა გაუძლოს. Blazor Server-ს მუდმივი კავშირი სჭირდება ბრაუზერსა და Kestrel-ს შორის მდგარ ყველა proxy-ში:
- WebSocket-ებმა upgrade უნდა გაიარონ. თუ ვერ გაიარეს, SignalR long polling-ზე გადადის, რაც მუშაობს, მაგრამ ყოველ მოვლენას ანელებს და მეტ მოთხოვნად ჯდება. ბრაუზერის network ჩანართი
101 Switching Protocolsპასუხს აჩვენებს, როცა WebSocket-ები მუშაობს. - proxy-ზე idle timeout-ები SignalR-ის keep-alive-ზე გრძელი უნდა იყოს, რომელიც ნაგულისხმევად ყოველ 15 წამში აგზავნის ping-ს.
- აპლიკაციამ forwarded header-ებით რეალური კლიენტი და სქემა უნდა დაინახოს - იხილე ASP.NET Core reverse proxy-ს უკან.
როცა კავშირი წყდება, ბრაუზერი ხელახლა დაკავშირების overlay-ს აჩვენებს და ცდილობს თავიდან. თუ retention პერიოდში ხელახლა დაუკავშირდა, circuit იქიდან გრძელდება, სადაც იყო. თუ არა, მდგომარეობა დაკარგულია და მომხმარებელმა გვერდი თავიდან უნდა ჩატვირთოს. მობილური მომხმარებლები, რომლებიც ქსელებს ცვლიან, და ძილიდან გამოღვიძებული ლეპტოპები ამას გამუდმებით აწყდებიან, და .NET 9-მაც და 10-მაც ხელახლა დაკავშირების გამოცდილება გააუმჯობესეს; .NET 10 ამატებს circuit-ის მდგომარეობის შენახვის გზას, რომ მომხმარებელმა უფრო ხანგრძლივი შესვენების შემდეგაც შეძლოს გაგრძელება. სანამ ამას დაეყრდნობი, შეამოწმე, რას უჭერს მხარს შენი ვერსია.
როგორ მუშაობს Blazor WebAssembly#
WebAssembly რეჟიმი შენს აპლიკაციას ბრაუზერში აგზავნის. პირველი ვიზიტი ჩამოტვირთავს WebAssembly-ში დაკომპილირებულ .NET runtime-ს, framework-ის იმ assembly-ებს, რომლებსაც შენი აპლიკაცია იყენებს, და შენს საკუთარ assembly-ებს, შემდეგ კი ყველაფერს ლოკალურად უშვებს. ამის შემდეგ ბრაუზერი ფაილებს ქეშავს და შემდგომი ვიზიტები სწრაფად იწყება.
კომპრომისები Server რეჟიმისას სარკისებურად ასახავს:
- ჩამოტვირთვა. გამოქვეყნებული აპლიკაცია trimmed-ია (WebAssembly-სთვის ნაგულისხმევად ჩართულია) და შეკუმშული, მაგრამ ელოდე პირველი ჩატვირთვის payload-ს, რომელიც მეგაბაიტებით იზომება და არა კილობაიტებით - პატარა აპლიკაცია შეკუმშულ სახით დაახლოებით 2-დან 4 MB-მდეა, უფრო დიდი - მეტი. ნელ მობილურ კავშირზე ეს ჩატვირთვის ეკრანის რამდენიმე წამია.
- საიდუმლოებები არ არის. კლიენტში ყველაფრის წაკითხვა მომხმარებელს შეუძლია. connection string-ები, API გასაღებები და ბიზნეს წესები, რომელთა გვერდის ავლაც არ უნდა იყოს შესაძლებელი, სერვერზე ეკუთვნის, API-ს უკან.
- შესრულების სიჩქარე. ნაგულისხმევად შენს კოდს WebAssembly runtime ინტერპრეტირებს. Ahead-of-time კომპილაცია (
<RunAOTCompilation>true</RunAOTCompilation>, რომლის ასაგებადაცwasm-toolsworkload სჭირდება) CPU-ზე მძიმე კოდს ბევრად აჩქარებს და ჩამოტვირთვას საგრძნობლად ზრდის. - სერვერის ხარჯი. UI-სთვის თითქმის არაფერი. სერვერი სტატიკურ ფაილებს თითო მომხმარებელს ერთხელ აწვდის და შემდეგ API გამოძახებებს პასუხობს, რომლებიც ნებისმიერი სხვა API-ის მსგავსად მასშტაბირდება.
WebAssembly აპლიკაციის ჰოსტინგი#
დამოუკიდებელი Blazor WebAssembly აპლიკაცია (blazorwasm შაბლონი) wwwroot-ში სტატიკური ფაილების საქაღალდედ ქვეყნდება და მას ნებისმიერი სტატიკური ჰოსტი მოემსახურება. სამი დეტალი წყვეტს, იმუშავებს თუ არა:
- Fallback routing. Blazor route-ებს ბრაუზერში ამუშავებს, ამიტომ
/orders/42-ზე მოთხოვნამindex.htmlუნდა დააბრუნოს და არა 404. სტატიკურ ჰოსტს უცნობი გზებისთვის rewrite წესი სჭირდება; როგორ დაამატებ, სერვერზეა დამოკიდებული. სტატიკური საიტის ჰოსტინგი ხშირ შემთხვევებს მოიცავს. - შეკუმშვა და MIME ტიპები. გამოქვეყნება ყოველი ფაილის წინასწარ შეკუმშულ
.brდა.gzასლებს წერს. მათი მიწოდება და.wasm-ისapplication/wasm-ად მიწოდება არის განსხვავება 3 MB-იან და 10 MB-იან პირველ ჩატვირთვას შორის. - ქეშის header-ები. runtime ფაილებს fingerprint აქვს, ამიტომ მათი დიდხანს ქეშირება შეიძლება;
index.html-ის - არა, თორემ მომხმარებლები deploy-ის შემდეგაც ძველ ვერსიებს ჩატვირთავენ. HTTP ქეშირების header-ები ახსნილი ამის არგუმენტაციას შეიცავს.
API, რომელსაც კლიენტი იძახებს, ცალკე ASP.NET Core აპლიკაციაა. თუ ის სტატიკური ფაილებისგან განსხვავებულ origin-ზეა, API-ზე CORS დააკონფიგურირე. Blazor Web App-ში InteractiveWebAssembly კომპონენტებით ASP.NET Core სერვერი კლიენტის ფაილებსაც და API-საც ერთი origin-იდან ემსახურება, რაც CORS-ს მთლიანად გამორიცხავს და ჰოსტინგისთვის ყველაზე მარტივი მოწყობაა.
Prerendering და ორმაგი ჩატვირთვა#
Blazor Web App-ში ინტერაქტიული კომპონენტები ნაგულისხმევად prerender-დება: სერვერი HTML-ს ერთხელ არენდერებს, რომ გვერდი მაშინვე გამოჩნდეს და საძიებო სისტემებმა წაიკითხონ, შემდეგ კი კომპონენტი ინტერაქტიულ რეჟიმში თავიდან იწყება და მეორედ რენდერდება. ამიტომ OnInitializedAsync-ში ნებისმიერი მონაცემის ჩატვირთვა ორჯერ ეშვება - ერთხელ prerendering-ის დროს, ერთხელ მაშინ, როცა circuit ან WebAssembly runtime იღებს სადავეებს.
ამასთან გამკლავების ორი გზა:
- შეინახე მდგომარეობა ორ რენდერს შორის.
PersistentComponentState(.NET 8-იდან) prerender-ის მონაცემებს გვერდში ასერიალიზებს და ინტერაქტიულ რენდერს გადასცემს. .NET 10 ამატებს დეკლარაციულ[PersistentState]ატრიბუტს კომპონენტის property-ზე, რომელიც იმავეს ნაკლები კოდით აკეთებს. - გამორთე prerendering იმ კომპონენტებისთვის, სადაც პირველ გამოსახვას მნიშვნელობა არ აქვს,
@rendermode @(new InteractiveServerRenderMode(prerender: false))-ით. მაშინ გვერდი ამ კომპონენტის ადგილას არაფერს აჩვენებს, სანამ ინტერაქტიულობა არ დაიწყება.
Prerendering ასევე ნიშნავს, რომ OnInitializedAsync-ში კოდი სერვერზე ეშვება WebAssembly კომპონენტისთვისაც, ამიტომ მან არ უნდა ივარაუდოს, რომ ბრაუზერშია - იქ IJSRuntime-ის გამოძახებები არ უნდა იყოს.
Deploy-ები, restart-ები და დაკარგული circuit-ები#
deploy პროცესს რესტარტავს და ყოველი Blazor Server circuit მასთან ერთად კვდება. მომხმარებლები ხელახლა დაკავშირების overlay-ს ხედავენ, ხელახლა დაკავშირება ვერ ხერხდება, რადგან სერვერი, რომელსაც იცნობდნენ, აღარ არსებობს, და მათ გვერდის თავიდან ჩატვირთვა უწევთ, რითაც ყველაფერს კარგავენ, რაც შენახული არ იყო. ჩართული deploy-on-push-ით ბრენჩზე ყოველი push ამას ყოველ დაკავშირებულ მომხმარებელს უკეთებს.
ასე რომ, Blazor Server აპლიკაციისთვის: მომხმარებლის შეყვანილი მონაცემები ხშირად შეინახე, deploy წყნარ დროს გააკეთე და circuit საცავად ნუ გამოიყენებ. WebAssembly აპლიკაციები გაცილებით შემწყნარებელია - UI ბრაუზერში აგრძელებს მუშაობას, სანამ API რესტარტდება, და მხოლოდ შესვენების დროს გაკეთებული გამოძახებები ვარდება. Zero-downtime deploy-ები პატარა სერვერზე განიხილავს, რის თავიდან აცილება შეგიძლია და რისი - არა ერთი ინსტანციით.
კიდევ ერთი რამ, რომელმაც restart-ს უნდა გადაურჩეს: Data Protection გასაღებები, რომლებიც antiforgery ტოკენებისა და ავთენტიფიკაციის cookie-ებისთვის გამოიყენება. თუ ისინი თავიდან დაგენერირდა, ყველა მომხმარებელი სისტემიდან გამოვა. ASP.NET Core აპლიკაციის deploy GitHub-იდან გაჩვენებს, სად შეინახო ისინი.
არჩევანი#
- ძირითადად კონტენტი და ფორმები: სტატიკური SSR, ინტერაქტიულობით მხოლოდ იმ კომპონენტებზე, რომლებსაც ის სჭირდება. ჰოსტინგისთვის ბევრად ყველაზე იაფი.
- შიდა ინსტრუმენტები და ადმინ პანელები ათეულობით მომხმარებლით სერვერთან ახლოს:
InteractiveServer. ასაშენებელი API არ არის, პირველი ჩატვირთვა სწრაფია, მეხსიერება ამ მასშტაბზე პრობლემა არ არის. - საჯარო აპლიკაციები ბევრი ერთდროული მომხმარებლით ან სერვერისგან შორს მყოფი მომხმარებლებით:
InteractiveWebAssemblyAPI-ით. სერვერი მოთხოვნებთან ერთად მასშტაბირდება და არა გახსნილ ჩანართებთან ერთად. - გინდა სწრაფი პირველი ჩატვირთვა და შემდეგ WebAssembly:
InteractiveAuto, იმის გათვალისწინებით, რომ ახლა წერ კომპონენტებს, რომლებიც ორივე ადგილას უნდა მუშაობდეს.
განხილული მაგალითი დაყოფას კონკრეტულს ხდის. სპორტული კლუბის დაჯავშნის საიტს აქვს საჯარო განრიგი, დაჯავშნის ფორმა და თანამშრომლების ეკრანი კორტების სამართავად. განრიგი სტატიკური SSR-ია stream rendering-ით: მას ყველაფერზე ბევრად მეტად კითხულობენ და ღიად დატოვება არაფერი უჯდება. დაჯავშნის ფორმაც სტატიკური SSR-ია - ვალიდაციით ჩვეულებრივ ფორმის გაგზავნას circuit არ სჭირდება. თანამშრომლების ეკრანი, რომელსაც კლუბის საკუთარ ქსელში ოთხი ადამიანი იყენებს, InteractiveServer-ია: მდიდარი, მყისიერი, პირდაპირ მონაცემთა ბაზასთან მოლაპარაკე. შედეგი პატარა გეგმაზე თავისუფლად მუშაობს, რადგან ერთადერთი არსებული circuit-ები იმ ოთხ ადამიანს ეკუთვნის, ვისაც მათგან სარგებელი აქვს. იგივე საიტი, მთლიანად Server რეჟიმში აგებული, circuit-ს შეინახავდა ყოველი წევრისთვის, რომელიც შაბათ დილით განრიგს ამოწმებს.
FAQ#
რამდენ მომხმარებელს გაუძლებს Blazor Server აპლიკაცია 2 GB-ზე?
ეს მთლიანად იმაზეა დამოკიდებული, რას ინახავს თითოეული circuit. მსუბუქი აპლიკაცია, რომელიც მომხმარებელზე ნახევარ მეგაბაიტს ინახავს, თავად პროცესთან ერთად რამდენიმე ასეულ ერთდროულ მომხმარებელს იტევს; მონაცემებით მძიმე აპლიკაცია შეიძლება რამდენიმე ათეულს გაუმკლავდეს. გაზომე ერთი circuit და გაამრავლე.
სჭირდება თუ არა Blazor WebAssembly-ს საერთოდ .NET სერვერი?
UI-სთვის არა. დამოუკიდებელი WebAssembly აპლიკაცია სტატიკური ფაილებია და მას ნებისმიერი სტატიკური ჰოსტი მოემსახურება. .NET სერვერი მხოლოდ იმ API-სთვის გჭირდება, რომელსაც ის იძახებს - და ის თითქმის ყოველთვის გექნება.
რატომ წყდება ჩემი Blazor Server აპლიკაციის კავშირი ყოველ წუთს?
proxy-ის idle timeout keep-alive ინტერვალზე მოკლეა, ან WebSocket-ები ვერ გადის და სარეზერვო transport გამუდმებით timeout-ზე ვარდება. network ჩანართში შეამოწმე, რომელი transport გამოიყენება.
შემიძლია Blazor Server-ის რამდენიმე სერვერზე მასშტაბირება?
კი, sticky session-ებით, რომ ყოველი მომხმარებლის კავშირი ყოველთვის იმ სერვერს აღწევდეს, რომელიც მის circuit-ს ინახავს. ერთ სერვერზე ეს კითხვა არ ჩნდება; SignalR real-time აპლიკაციები ჩვეულებრივი SignalR-ის scale-out-ს განიხილავს.
InteractiveAuto ორივეს საუკეთესო მხარეა?
საჯარო აპლიკაციებისთვის ის კარგი ნაგულისხმევია, მაგრამ ყოველი Auto კომპონენტი სერვერზეც და ბრაუზერშიც უნდა მუშაობდეს, ამიტომ მონაცემთა ბაზას პირდაპირ ვერ შეეხება. ეს შეზღუდვა სწრაფი პირველი ჩატვირთვის ფასია.




კომენტარები
სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.