【问题标题】:wss fails over https on apache serverwss 在 apache 服务器上对 https 进行故障转移
【发布时间】:2015-09-01 13:58:07
【问题描述】:

我在数字海洋中有一台服务器,它使用 StartCOM I 类主要中间 CA 进行 ssl。我已经为你设置了一个 websocket 服务器,我想从一个由 https 提供的页面连接到它。

当我尝试仅使用 http 连接到 websocket 时,它工作正常。但是,当我尝试通过将 websocket uri 从 ws 更改为 wss 来通过 https 使用它时,它不会连接。

我做错了什么。使用 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 )
        }
    }
};

客户端 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);

?>

服务器屏幕截图

它一直断开连接

【问题讨论】:

  • 你能提供你的代码吗?
  • 你有没有解决过这个问题?我正在使用完全相同的代码并将我的网站也更改为 HTTPS。
  • @GillesLesire 我搬到了 firebase,它满足了我对实时聊天应用程序的需求。但我认为当您使用免费 SSL 或您的 SSL 无效或过期时会出现此问题。
  • 我有一个合法的 SSL,所以这不是问题。也许我必须通过我的 SSL 配置或其他方式在该特定端口上允许 SSL,我将不得不继续寻找。不过感谢您的回复。
  • 使用 stunnel 将安全端口转发到不安全端口修复了该作业。唯一的问题是您无法再检索主机 IP 地址。都是127.0.0.1

标签: php ssl websocket wss


【解决方案1】:

我遇到了同样的问题(我什至使用相同的 PHP 脚本)并设法使用 stunnel 解决了这个问题。通过来自各种不同的、相互矛盾的来源的大量试验和错误,我设法让它运行起来。但是,您将不再获得客户端 IP 地址,如果需要,您必须手动将其发送到服务器。我在某处读到您可以使用代理转发客户端 IP,但我自己还无法设置。

在服务器上安装 stunnel

通过 ssh 登录到您的服务器,确保您的系统完全是最新的。

apt-get update
apt-get upgrade

安装stunnel包

apt-get install stunnel4 -y

配置通道

通过运行以下命令为 stunnel 创建配置文件

nano /etc/stunnel/stunnel.conf

将以下内容写入文件

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

就我个人而言,我只是为 stunnel 使用了与 HTTPS 设置相同的证书。

运行通道

你必须保持 stunnel 运行,就像你必须保持 websocket 运行一样。 使用命令执行此操作:

/etc/init.d/stunnel4 restart

更改您的 PHP 脚本

更改 PHP 文件 server.php

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

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

修改客户端 JS 脚本

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

应该改为

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

因此,如果您正在运行 stunnel 和 websocket,您现在应该能够再次通过套接字发送和接收数据,唯一的区别是,根据 websocket 脚本,所有客户端现在似乎都来自 127.0.0.1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 2012-09-14
    • 2015-05-09
    • 1970-01-01
    相关资源
    最近更新 更多