Configurarea unui websocket pe Apache? (Programare, Apache, Websocket)

user1846065 a intrebat.

Deci, fac niște cercetări despre websocket-uri și am câteva întrebări la care nu găsesc un răspuns definitiv:

  • Cum pot configura un web socket pe serverul meu Linux? Există un modul Apache? Aș putea trebuie să am să folosesc un cod PHP terță parte sau ceva similar?

  • Există vreun fel de dezavantaje la metoda descrisă la întrebarea 1 de care ar trebui să fiu conștient, în afară de compatibilitatea cu browserul?

  • Cum aș putea „upgrada” instalarea mea de websocket la o instalare websocket securizată (de la ws:// la wss://)? Acest lucru ar fi mai ușor sau mai dificil dacă SSL ar fi deja configurat pe serverul meu Apache?

  • Există vreun alt limbaj pe care l-aș putea folosi pentru a mă conecta la socket-ul meu web decât JavaScript?

  • Care este metoda de solicitare implicită pentru un socket web?

Comentarii

  • Doar un sfat, acum că am câțiva ani de experiență în domeniul socket-urilor web… NGINX este mult mai bun decât Apache pentru acest lucru. NGINX a fost creat inițial pentru a fi un server proxy, așa că, în mod natural, este mult mai stabil ca proxy decât Apache. Cât despre care este un server web mai bun este un alt subiect… – user1846065
  • Ați încercat mod_proxy_wstunnel de la Apache? Și cum ai făcut comunicarea din PHP? Ați folosit vreo bibliotecă terță parte pentru a face acest lucru? –  > Por Airy.
  • Din nou, din experiența mea, NGINX este mult mai bun pentru proxy-ul wstunnel. Am încercat mod_proxy_wstunnel și a funcționat bine, dar a cauzat probleme pentru conexiunile care au rămas deschise mai multe zile. Am folosit PHP la început și nu-mi amintesc ce am folosit, dar acum îmi scriu backend-ul de socket web în C, iar C este excelent pentru gestionarea socket-urilor. PHP nu a fost făcut pentru a rula ca proces pentru perioade lungi de timp. socketo.me este totuși o referință bună pentru un server de socket web PHP. developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/… este un ghid frumos pentru a ajuta la învățare. – user1846065
3 răspunsuri
eepp

Nu pot răspunde la toate întrebările, dar voi face tot ce pot.

După cum știți deja, WS este doar o conexiune TCP full-duplex persistentă cu mesaje încadrate, în care handshaking-ul inițial este de tip HTTP. Aveți nevoie de un server care să asculte cererile WS primite și care să le lege un handler.

Acum ar putea fi posibil cu Apache HTTP Server și am văzut câteva exemple, dar nu există un suport oficial și devine complicat. Ce ar face Apache? Unde ar fi handlerul? Există un modul care redirecționează cererile WS primite către o bibliotecă partajată externă, dar acest lucru nu este necesar cu celelalte instrumente grozave pentru a lucra cu WS.

Tendințele serverului WS includ acum: Autobahn (Python) și Socket.IO (Node.js = JavaScript pe server). Acesta din urmă suportă și alte conexiuni „persistente” hackish, cum ar fi pollingul lung și toate COMET chestii. Există și alte cadre de server WS puțin cunoscute, cum ar fi Ratchet (PHP, dacă sunteți familiarizat doar cu acesta).

În orice caz, va trebui să ascultați pe un port și, bineînțeles, acel port nu poate fi același cu cel al serverului Apache HTTP care rulează deja pe mașina dumneavoastră (implicit = 80). Ați putea folosi ceva de genul 8080, dar chiar dacă acesta este o alegere populară, unele firewall-uri ar putea totuși să-l blocheze, deoarece nu ar trebui să fie trafic Web. Acesta este motivul pentru care mulți oameni aleg 443, care este HTTP securizat port pe care, din motive evidente, firewall-urile nu îl blochează. Dacă nu folosiți SSL, puteți utiliza 80 pentru HTTP și 443 pentru WS. Serverul WS nu trebuie să fie securizat; noi doar folosim portul.

Editați: Conform lui Iharob Al Asimi, paragraful anterior este greșit. Nu am timp să investighez acest lucru, așa că vă rog să consultați lucrarea sa pentru mai multe detalii.

În ceea ce privește protocolul, după cum urmează Wikipedia arată, , acesta arată astfel:

Clientul trimite:

GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com

Serverul răspunde:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

și menține conexiunea în viață. Dacă puteți implementa acest handshaking și încadrarea de bază a mesajelor (încapsularea fiecărui mesaj cu un mic antet care îl descrie), atunci puteți utiliza orice limbaj de client doriți. JavaScript este utilizat doar în browserele web, deoarece este încorporat.

După cum puteți vedea, „metoda de solicitare” implicită este o metodă inițială HTTP GET, deși aceasta nu este chiar HTTP și pierde tot ce are în comun cu HTTP după acest handshaking. Presupun că serverele care nu acceptă

Upgrade: websocket
Connection: Upgrade

vor răspunde cu o eroare sau cu conținutul unei pagini.

Comentarii

  • Mulțumesc pentru contribuție. M-am jucat mult cu acest lucru noaptea trecută, iar răspunsul dvs. m-a ajutat să înțeleg câteva lucruri. Deși nu răspunde la tot, cu siguranță mă îndrumă în direcția corectă. Voi folosi probabil Rachet pentru că serverul rulează deja PHP. Presupun că cea mai mare întrebare pe care o am în acest moment și la care nu voi găsi răspuns dacă mă joc cu recomandările dumneavoastră este „De ce porturile implicite pentru websocket se suprapun peste porturile implicite pentru HTTP?”. – user1846065
  • Pentru că este conceput pentru a fi integrat cu un server HTTP. Cu toate acestea, nu cred că Apache HTTP Server are o modalitate simplă de a face acest lucru pentru moment. Dar cu cadrele menționate mai sus, ar trebui să fie ușor să servești și HTTP, astfel încât să poți renunța complet la Apache HTTP Server. Va trebui să furnizați gestionari diferiți pentru diferite căi de context (de ex. /myWsEndpoint duce la un gestionar WS și /hello către un punct final HTTP). De asemenea, am uitat să menționez Jetty care este destul de frumos și ușor pentru programatorul Java (servește atât HTTP, cât și WS). –  > Por eepp.
  • Înțeleg. Mulțumesc pentru tot ajutorul dumneavoastră. Voi mai face câteva experimente cu acest lucru după muncă. – user1846065
  • I downvote because desigur, poate fi același port pe care apache îl folosește pentru HTTP obișnuit. –  > Por Iharob Al Asimi.
  • De fapt, am reușit să scriu un modul apache care să se ocupe de handshake-ul protocolului WS și să comunice cu un alt program care va fi în cuvintele tale „gestionarul„. Este foarte simplu și robust. Ah, și folosește portul 80. De fapt, acesta este porțiunea implicită din API-ul javascript websocket. –  > Por Iharob Al Asimi.
Udo

Noua versiune 2.4 a serverului HTTP Apache are un modul numit mod_proxy_wstunnel, care este un proxy de websocket.

http://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

Comentarii

  • Trebuie să activați mod_proxy și mod_proxy_wstunnel module și să adăugați ProxyPass /wss2/ ws://YOUR_DOMAIN:WS_PORT/ în httpd.conf fișier. Utilizați schema securizată fără numărul de port url în apelul JS (de ex. var ws = new WebSocket("wss://YOUR_DOMAIN/wss2/NNN"); A se vedea Ref –  > Por webcoder.
  • Ați acceptat acest lucru pe deplin websocket –  > Por Veshraj Joshi.
Sunil Kumar

M-am străduit să înțeleg setările proxy pentru websockets pentru https prin urmare, permiteți-mi să pun claritate aici ceea ce am realizat.

În primul rând trebuie să activați proxy și proxy_wstunnel modulele apache și fișierul de configurare apache va arăta astfel.

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
      ServerName www.example.com
        ServerAdmin [email protected]
        DocumentRoot /var/www/your_project_public_folder

      SSLEngine on
      SSLCertificateFile    /etc/ssl/certs/path_to_your_ssl_certificate
      SSLCertificateKeyFile /etc/ssl/private/path_to_your_ssl_key

      <Directory /var/www/your_project_public_folder>
              Options Indexes FollowSymLinks
              AllowOverride All
              Require all granted
              php_flag display_errors On
      </Directory>
      ProxyRequests Off 
      ProxyPass /wss/  ws://example.com:port_no

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
</IfModule>

în aplicația dvs. frontend utilizați adresa url "wss://example.com/wss/" acest lucru este foarte important mai ales dacă sunteți blocat cu websockets s-ar putea să faceți o greșeală în url-ul front-end. Probabil că ați pus url-ul greșit, așa cum este mai jos.

wss://example.com:8080/wss/ -> port no should not be mentioned
ws://example.com/wss/ -> url should start with wss only.
wss://example.com/wss -> url should end with / -> most important

De asemenea, partea interesantă este ultima /wss/ este același cu proxypass valoare dacă scrieți proxypass /ws/ atunci în front-end ar trebui să scrieți /ws/ la sfârșitul url-ului.