Przepraszam za długość, to trochę konieczne.
Wprowadzenie
Tworzę oprogramowanie do zdalnego pulpitu (dla zabawy) w C # 4.0 dla Windows Vista / 7. Przeszedłem przez podstawowe przeszkody: mam niezawodny system przesyłania wiadomości UDP, stosunkowo czysty projekt programu, mam uruchomiony i działający sterownik lustrzany (bezpłatny sterownik lustrzany DFMirage z DemoForge) i zaimplementowałem przechodzenie NAT dla wszystkich Typy NAT z wyjątkiem symetrycznych NAT (obecnych w firmowych firewallach).
Jeśli chodzi o przesyłanie / udostępnianie ekranu, dzięki sterownikowi lustrzanemu, jestem automatycznie powiadamiany o zmienionych regionach ekranu i mogę po prostu przenieść stale zmieniającą się mapę bitową ekranu sterownika lustrzanego do mojej własnej mapy bitowej. Następnie kompresuję obszar ekranu jako plik PNG i wysyłam go z serwera do mojego klienta. Wszystko wygląda całkiem nieźle, ale nie jest wystarczająco szybkie. Jest tak samo wolny jak VNC (przy okazji, nie używam protokołu VNC, tylko niestandardowy protokół amatorski).
Od najwolniejszego oprogramowania do zdalnego pulpitu do najszybszego, lista zwykle zaczyna się we wszystkich implementacjach podobnych do VNC, następnie pnie się do Microsoft Windows Remote Desktop… a potem… TeamViewer. Nie jestem pewien co do CrossLoop, LogMeIn - nie korzystałem z nich, ale TeamViewer jest niesamowicie szybki. Dosłownie na żywo. Uruchomiłem tree
polecenie w wierszu polecenia i zaktualizowałem je z opóźnieniem 20 ms. Mogę przeglądać Internet o kilka milisekund wolniej niż na moim laptopie. Przewijanie kodu w pionie w programie Visual Studio ma 50 ms opóźnienia. Pomyśl o tym, jak solidne musi być rozwiązanie do przenoszenia ekranu TeamViewer, aby to wszystko osiągnąć.
VNC używają haków opartych na ankietach do wykrywania zmian ekranu i przechwytywania / porównywania ekranu brutalnej siły w najgorszym przypadku. W najlepszym przypadku używają sterownika lustrzanego, takiego jak DFMirage. Jestem na tym poziomie. I używają czegoś, co nazywa się protokołem RFB.
Pulpit zdalny Microsoft Windows najwyraźniej idzie o krok wyżej niż VNC. Słyszałem gdzieś na StackOverflow, że Pulpit zdalny systemu Windows nie wysyła bitmap ekranu, ale rzeczywiste polecenia rysowania. To całkiem genialne, ponieważ może po prostu wysłać prosty tekst (narysuj ten prostokąt na tej współrzędnej i pokoloruj go tym gradientem)! Pulpit zdalny jest naprawdę szybki - i jest to standardowy sposób pracy z domu. I używa czegoś, co nazywa się protokołem RDP.
Teraz TeamViewer jest dla mnie kompletną tajemnicą. Najwyraźniej wydali swój kod źródłowy dla wersji 2 (TeamViewer jest wersją 7 od lutego 2012). Ludzie to przeczytali i powiedzieli, że wersja 2 jest bezużyteczna - to tylko kilka ulepszeń w stosunku do VNC z automatycznym przechodzeniem NAT.
Ale wersja 7 ... jest teraz absurdalnie szybka. To znaczy, jest faktycznie szybszy niż Pulpit zdalny systemu Windows. Strumieniowałem gry DirectX 3D z TeamViewer (przy 1 fps, ale Pulpit zdalny Windows nie pozwala nawet na uruchomienie DirectX).
Nawiasem mówiąc, TeamViewer robi to wszystko bez sterownika lustrzanego. Istnieje opcja zainstalowania jednego i robi się to trochę szybciej.
Pytanie
Moje pytanie brzmi: w jaki sposób TeamViewer jest tak szybki?To nie może być możliwe. Jeśli masz rozdzielczość 1920 na 1080 przy nawet 24-bitowej głębi (16-bitowa głębia byłaby zauważalnie brzydka), to nadal 6220800 bajtów surowych. Nawet użycie libjpeg-turbo (jednej z najszybszych bibliotek kompresji JPG używanych przez duże korporacje), skompresowanie jej do 30 KB (bądźmy niezwykle hojni), zajęłoby trochę czasu, aby przejść przez serwery TeamViewer (TeamViewer omija korporacyjne Symmetric NAT, po prostu przekazując ruch przez ich serwery). Kompresja libjpeg-turbo zajęłaby trochę czasu. Wysokiej jakości kompresja JPG zajmuje dla mnie 175 milisekund dla pełnego zrzutu ekranu 1920 na 1080. Ta liczba rośnie, jeśli komputer hosta obsługuje procesor Atom. Po prostu nie rozumiem, w jaki sposób TeamViewer tak dobrze zoptymalizował przesyłanie ekranu. Obrazy o małym rozmiarze mogą być mocno skompresowane, ale kompresja zajmuje co najmniej kilkadziesiąt milisekund. Obrazy o dużym rozmiarze nie wymagają czasu na kompresję, ale przejście przez nie zajmuje dużo czasu. W jakiś sposób TeamViewer kończy cały proces, uzyskując około 20-25 klatek na sekundę. Użyłem monitora sieci, a TeamViewer nadal działa bez opóźnień przy prędkościach 500 Kb / s i 1 Mb / s (opóźnienie oprogramowania VNC przez kilka sekund przy tej szybkości transferu). Podczas mojegotree
Test wiersza polecenia, TeamViewer odbierał dane przychodzące z szybkością 1 Mb / si nadal działał 5-6 fps. VNC i zdalny pulpit tego nie robią. Więc jak?
Odpowiedzi będą nieco skomplikowane i zawiłe, więc nie wysyłaj swoich 0,02 USD, jeśli chcesz tylko powiedzieć, że to dlatego, że używają UDP zamiast TCP (czy uwierzyłbyś, że faktycznie używają TCP tak samo skutecznie).
Mam nadzieję, że gdzieś tutaj w StackOverflow jest programista TeamViewer.
Potencjalne odpowiedzi
Zaktualizuje to, gdy ludzie odpowiedzą.
- Przede wszystkim myślę, że TeamViewer ma bardzo dobrą kontrolę sieci. Na przykład dzielą duże pakiety do rozmiaru tuż poniżej MTU i nigdy nie marnują podróży. Prawdopodobnie mają różnego rodzaju fantazyjne zaczepy do wykrywania zmian na ekranie, a także niezwykle szybkie porównania obrazów XOR.
Odpowiedzi:
Najbardziej podstawową rzeczą jest prawdopodobnie to, że nie chcesz przesyłać statycznych obrazów, a jedynie zmiany w obrazach, co zasadniczo jest analogiczne do strumienia wideo .
Moim najlepszym przypuszczeniem jest jakiś bardzo wydajny (i mocno wyspecjalizowany i zoptymalizowany) algorytm kompensacji ruchu, ponieważ większość rzeczywistych zmian w ogólnym zastosowaniu pulpitu to liniowy ruch elementów (przewijanie tekstu, przesuwanie okien itp. W przeciwieństwie do transformacji elementów).
Wydajność DirectX 3D 1 FPS wydaje się w pewnym stopniu potwierdzać moje przypuszczenia.
źródło
Przekonasz się, że TeamViewer rzadko musi przekazywać ruch przez własne serwery. TeamViewer penetruje NAT i sieci skomplikowane przez NAT przy użyciu translacji NAT (myślę, że jest to dziurkowanie UDP , jak libjingle Google ).
Używają własnych serwerów jako pośrednik w celu uzgadniania i konfigurowania połączenia, ale w większości przypadków relacja między klientem a serwerem będzie miała charakter P2P (w najlepszym przypadku, gdy uścisk dłoni się powiedzie). Jeśli przechodzenie NAT się nie powiedzie, TeamViewer rzeczywiście przekaże ruch przez własne serwery.
Jednak widziałem, jak robi to tylko wtedy, gdy klient stoi za podwójnym NATem.
źródło
Trochę późna odpowiedź, ale proponuję przyjrzeć się niezbyt znanemu projektowi na codeplex o nazwie ConferenceXP
Zapewnione jest pełne źródło (jest ogromne!). Implementuje protokół RTP .
źródło
Rzeczywiście brzmi to bardziej jak strumieniowe przesyłanie wideo niż strumieniowanie obrazu, jak ktoś sugerował. Kompresja JPEG / PNG nie jest przeznaczona dla tego typu prędkości, więc zapomnij o nich.
Wyobraź sobie, że masz w systemie kodek do nagrywania, który może nagrywać w czasie rzeczywistym przychodzący strumień wideo (Twój ekran). Może trochę jak Fraps. Następnie wyobraź sobie kodek odtwarzania wideo po drugiej stronie (klient zdalny). Ponieważ nagrywarki HD mogą to zrobić (nagrywać na żywo, a nawet odtwarzać na żywo z tego samego HD), tak samo powinieneś w końcu. HD z pewnością nie może dostarczyć obrazów szybciej, niż możesz odczytać wyświetlacz, więc to nie jest wąskie gardło. Wąskie gardło to kodeki wideo. Przekonasz się, że koder jest znacznie większym problemem niż dekoder, ponieważ wszystkie dekodery są w większości bezpłatne.
Nie mówię, że to proste; Sam użyłem DirectShow do zakodowania pliku wideo i zdecydowanie nie jest to w czasie rzeczywistym. Ale biorąc pod uwagę odpowiedni kodek, jestem przekonany, że może działać.
źródło
Moje przypadkowe przypuszczenie to: telewizor używa kodeka x264, który ma licencję komercyjną (w przeciwnym razie TeamViewer musiałby udostępnić ich kod źródłowy). Przypominam sobie, że w pewnym momencie (ponad 5 lat temu) główny twórca x264 napisał artykuł o ulepszeniach, które wprowadził do kodowania z niskim opóźnieniem (jeśli opóźnisz o kilka ramek, kodery mogą lepiej kompresować), a także wspomniał o innych ulepszeniach, które były odpowiednie do użytku w stylu TeamViewer. W tym poście wspomniał o graniu w quake over video bez żadnych zauważalnych problemów. Wtedy byłem pewien, kto jest sponsorem tych ulepszeń, ponieważ TeamViewer był wtedy właściwie jedyną opcją. x264 to otwarta implementacja kodeka wideo H264i jest to niesamowicie dobra implementacja, najlepsza. Jednocześnie jest niezwykle dobrze zoptymalizowany. Najprawdopodobniej dzięki wyjątkowo dobrej implementacji x264 uzyskasz znacznie lepsze wyniki z telewizorem przy mniejszym obciążeniu procesora. AnyDesk i Chrome Remote Desk używają biblioteki libvpx, która nie jest tak dobra jak x264 (pod względem optymalizacji i jakości wideo).
Jednak nie sądzę, że TeamView może pokonać RDP firmy Microsoft. Dla mnie jest najlepszy, jednak działa tylko między komputerami z systemem Windows lub z komputera Mac na system Windows. Telewizor działa nawet z telefonów komórkowych.
Aktualizacja: artykuł został napisany w styczniu 2010 roku, więc praca została wykonana około 10 lat temu. Poza tym popełniłem błąd: zagrał wezwanie do służby, a nie trzęsienie. Kiedy zamieściłeś swoje pytanie, jeśli moje przypuszczenia są prawidłowe, TeamViewer korzystał z tej pracy przez 3 lata. Przeczytaj ten post na blogu z archiwum internetowego: x264: najlepsza na świecie platforma do strumieniowego przesyłania wideo o niskim opóźnieniu . Kiedy przeczytałem ten artykuł w 2010 roku, byłem pewien, że „startupem - który zażądał, aby nie być nazywane”, o którym wspomina autor, to TeamViewer.
źródło
Dziwnie. ale z mojego doświadczenia wynika, że TeamViewer nie jest szybszy / bardziej responsywny niż VNC, tylko łatwiejszy w konfiguracji. Mam kilka win-boxenów, do których podłączam VNC przez OpenVPN (więc jest kolejna warstwa napowietrzna) i to na tanim kablu (512 w górę) i uważam, że prawidłowo skonfigurowany TightVNC jest znacznie bardziej responsywny niż TeamViewer do tego samego boxena. RDP (naturalnie) nawet bardziej, ponieważ w dużej mierze wysyła polecenia rysowania GUI zamiast kafelków bitmapowych.
Co prowadzi nas do:
Dlaczego nie używasz VNC? Istnieje mnóstwo rozwiązań open source, a Tight prawdopodobnie jest teraz na szczycie swojej gry.
Zaawansowane implementacje VNC wykorzystują kompresję stratną, która wydaje się osiągać lepsze wyniki niż wybór PNG. Ponadto IIRC reszta ładunku jest również zgniatana za pomocą zlib. Zarówno j Tight, jak i UltraVNC mają bardzo zoptymalizowane algorytmy, szczególnie dla systemu Windows. Poza tym Tight jest open-source.
Jeśli twoim głównym celem są wygrane boxen, RDP może być lepszą opcją i ma implementację open source (rdesktop)
Jeśli * nix boxen jest twoim głównym celem, NX może być lepszą opcją i ma implementację open source (FreeNX, choć nie tak zoptymalizowany jak zastrzeżony produkt NoMachine).
Jeśli kompresja JPEG jest problemem z wydajnością twojego algo, jestem prawie pewien, że porównanie obrazów nadal zmniejszyłoby wydajność. Założę się, że używają kompresji w najlepszym przypadku dla każdej konkretnej sytuacji, tj. Stratnej dla dużych klatek, niektórych szybkich i brudnych wewnętrznych bez przegranych dla mniejszych, porównują fragmenty obrazów i wysyłają tylko różne typy i kilka innych sztuczek optymalizacyjnych.
I wiele z tych sztuczek musi być obecnych w Tight> 2.0, ponieważ znowu, z mojego doświadczenia, bije to piekło w wydajności TeamViewer wyse, YMMV.
Również wybór skompilowanego środowiska uruchomieniowego JIT zamiast czegoś takiego jak C ++ może trochę zmniejszyć wydajność, szczególnie na maszynach z ograniczoną pamięcią (wiele dostrajania wydajności idzie do toalety, gdy Windows zaczyna intensywnie używać pliku stronicowania). Będziesz potrzebował pamięci, aby zachować poprzednie stany obrazu w celu wewnętrznego porównania tego, co daje DF mirage.
źródło