Setting up a websocket on Apache?

前端 未结 3 655
悲哀的现实
悲哀的现实 2020-12-03 00:53

So I\'m doing some research on websockets, and I have a few questions I can\'t seem to find a definitive answer for:

  • How can I set up a web socket on my Lin

相关标签:
3条回答
  • 2020-12-03 01:14

    The new version 2.4 of Apache HTTP Server has a module called mod_proxy_wstunnel which is a websocket proxy.

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

    0 讨论(0)
  • 2020-12-03 01:18

    I can't answer all questions, but I will do my best.

    As you already know, WS is only a persistent full-duplex TCP connection with framed messages where the initial handshaking is HTTP-like. You need some server that's listening for incoming WS requests and that binds a handler to them.

    Now it might be possible with Apache HTTP Server, and I've seen some examples, but there's no official support and it gets complicated. What would Apache do? Where would be your handler? There's a module that forwards incoming WS requests to an external shared library, but this is not necessary with the other great tools to work with WS.

    WS server trends now include: Autobahn (Python) and Socket.IO (Node.js = JavaScript on the server). The latter also supports other hackish "persistent" connections like long polling and all the COMET stuff. There are other little known WS server frameworks like Ratchet (PHP, if you're only familiar with that).

    In any case, you will need to listen on a port, and of course that port cannot be the same as the Apache HTTP Server already running on your machine (default = 80). You could use something like 8080, but even if this particular one is a popular choice, some firewalls might still block it since it's not supposed to be Web traffic. This is why many people choose 443, which is the HTTP Secure port that, for obvious reasons, firewalls do not block. If you're not using SSL, you can use 80 for HTTP and 443 for WS. The WS server doesn't need to be secure; we're just using the port.

    Edit: According to Iharob Al Asimi, the previous paragraph is wrong. I have no time to investigate this, so please see his work for more details.

    About the protocol, as Wikipedia shows, it looks like this:

    Client sends:

    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
    

    Server replies:

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

    and keeps the connection alive. If you can implement this handshaking and the basic message framing (encapsulating each message with a small header describing it), then you can use any client-side language you want. JavaScript is only used in Web browsers because it's built-in.

    As you can see, the default "request method" is an initial HTTP GET, although this is not really HTTP and looses everything in common with HTTP after this handshaking. I guess servers that do not support

    Upgrade: websocket
    Connection: Upgrade
    

    will reply with an error or with a page content.

    0 讨论(0)
  • 2020-12-03 01:31

    I struggled to understand the proxy settings for websockets for https therefore let me put clarity here what i realized.

    First you need to enable proxy and proxy_wstunnel apache modules and the apache configuration file will look like this.

    <IfModule mod_ssl.c>
        <VirtualHost _default_:443>
          ServerName www.example.com
            ServerAdmin webmaster@localhost
            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>
    

    in your frontend application use the url "wss://example.com/wss/" this is very important mostly if you are stuck with websockets you might be making mistake in the front end url. You probably putting url wrongly like below.

    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
    

    also interesting part is the last /wss/ is same as proxypass value if you writing proxypass /ws/ then in the front end you should write /ws/ in the end of url.

    0 讨论(0)
提交回复
热议问题