wss fails over https on apache server

匿名 (未验证) 提交于 2019-12-03 08:57:35

问题:

I have a server in digital ocean which is using StartCOM class I primary intermediate CA for ssl. I have set u a websocket server and I want to make a connection to it from a page which is served by https.

When I try to connect to the websocket using just http it works fine. But when I try to use it over https by changing the websocket uri from ws to wss it does not connect.

What am I doing wrong. Connection is made using fancywebsockets.js

fancywebsockets.js

var FancyWebSocket = function(url) {     var callbacks = {};     var ws_url = url;     var conn;      this.bind = function(event_name, callback){         callbacks[event_name] = callbacks[event_name] || [];         callbacks[event_name].push(callback);         return this;// chainable     };      this.send = function(event_name, event_data){         this.conn.send( event_data );         return this;     };      this.connect = function() {         if ( typeof(MozWebSocket) == 'function' )             this.conn = new MozWebSocket(url);         else             this.conn = new WebSocket(url);          // dispatch to the right handlers         this.conn.onmessage = function(evt){             dispatch('message', evt.data);         };          this.conn.onclose = function(){dispatch('close',null)}         this.conn.onopen = function(){dispatch('open',null)}     };      this.disconnect = function() {         this.conn.close();     };      var dispatch = function(event_name, message){         var chain = callbacks[event_name];         if(typeof chain == 'undefined') return; // no callbacks for this event         for(var i = 0; i < chain.length; i++){             chain[i]( message )         }     } }; 

Client Side JS

var Server;          function log( text ) {         console.log(text)      }          function send( text ) {             Server.send( 'message', text );         }          $(document).ready(function() {             log('Connecting...');             Server = new FancyWebSocket('ws://www.myserver.com:9400');              $('#message').keypress(function(e) {                 if ( e.keyCode == 13 && this.value ) {                     log( 'You: ' + this.value );                     send( this.value );                   }             });              //Let the user know we're connected             Server.bind('open', function() {                 log( "Connected." );             });              //OH NOES! Disconnection occurred.             Server.bind('close', function( data ) {                 log( "Disconnected." );             });              //Log any messages sent from server             Server.bind('message', function( payload ) {                 log( payload );             });              Server.connect();         }); 

Server.php

<?php // prevent the server from timing out set_time_limit(0);  // include the web sockets server script (the server is started at the far bottom of this file) require 'class.PHPWebSocket.php';  // when a client sends data to the server function wsOnMessage($clientID, $message, $messageLength, $binary) {     global $Server;     $ip = long2ip( $Server->wsClients[$clientID][6] );      // check if message length is 0     if ($messageLength == 0) {         $Server->wsClose($clientID);         return;     }      //The speaker is the only person in the room. Don't let them feel lonely.     if ( sizeof($Server->wsClients) == 1 )         $Server->wsSend($clientID, "There isn't anyone else in the room, but I'll still listen to you. --Your Trusty Server");     else         //Send the message to everyone but the person who said it         foreach ( $Server->wsClients as $id => $client )             if ( $id != $clientID )                 $Server->wsSend($id, "Visitor $clientID ($ip) said \"$message\""); }  // when a client connects function wsOnOpen($clientID) {     global $Server;     $ip = long2ip( $Server->wsClients[$clientID][6] );      $Server->log( "$ip ($clientID) has connected." );      //Send a join notice to everyone but the person who joined     foreach ( $Server->wsClients as $id => $client )         if ( $id != $clientID )             $Server->wsSend($id, "Visitor $clientID ($ip) has joined the room."); }  // when a client closes or lost connection function wsOnClose($clientID, $status) {     global $Server;     $ip = long2ip( $Server->wsClients[$clientID][6] );      $Server->log( "$ip ($clientID) has disconnected." );      //Send a user left notice to everyone in the room     foreach ( $Server->wsClients as $id => $client )         $Server->wsSend($id, "Visitor $clientID ($ip) has left the room."); }  // start the server $Server = new PHPWebSocket(); $Server->bind('message', 'wsOnMessage'); $Server->bind('open', 'wsOnOpen'); $Server->bind('close', 'wsOnClose'); // for other computers to connect, you will probably need to change this to your LAN IP or external IP, // alternatively use: gethostbyaddr(gethostbyname($_SERVER['SERVER_NAME'])) $Server->wsStartServer('my.ip.add.ress', 9400);  ?> 

Server Screen Shot

It keeps on getting disconnected

回答1:

I ran into the same issue (I even use the same PHP script) and manage to resolve this using stunnel. With a lot of trial-and-error from all kind of different, contradicting sources I managed to get it running. However you won't get client ip addresses anymore, you'll have to send it to the server manually if you need it. I read somewhere that you could forward the client IP using proxy but haven't yet been able to set that up myself.

Install stunnel on server

Login to your server through ssh make sure your system is fully up to date.

apt-get update apt-get upgrade 

Install the stunnel package

apt-get install stunnel4 -y 

Configure stunnel

Create a config file for stunnel by running the following command

nano /etc/stunnel/stunnel.conf 

Write the following into the file

foreground = yes key = /path/to/your/ssl/cert.key cert =  /path/to/your/ssl/cert.pem CAfile = /path/to/your/ssl/cert.pem debug = 7 output = /var/log/stunnel_websocket.log  [websocket] accept = myserver.com:9401 connect = 9400 

Personally I just used the same certificate for the stunnel as I did for the HTTPS setup.

Run the stunnel

You have to keep the stunnel running like you have to keep the websocket running. Do this with the command:

/etc/init.d/stunnel4 restart 

Alter your PHP script

Change the PHP file server.php

$Server->wsStartServer('my.ip.add.ress', 9400); 

to

$Server->wsStartServer('localhost', 9400); 

Alter the client side JS script

Server = new FancyWebSocket('ws://www.myserver.com:9400'); 

should be changed to

Server = new FancyWebSocket('wss://www.myserver.com:9401'); 

So if you are running the stunnel and the websocket you should now be able to send and receive data over the socket again with the only difference that all clients now appear to be coming from 127.0.0.1 according to the websocket script.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!