質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
さくらのVPS

さくらのVPSは、さくらインターネット社が提供するVPS(仮想専用サーバー)です。高速なSSDの選択や複数台構成も可能。利用者に応じた柔軟なプランが用意されています。大規模システムにも対応可能なスケーラビリティを備えたホスティングサービスです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

2337閲覧

さくらのVPS環境にて、WebSocket(Ratchet)のSSL通信が失敗する

fenjapa

総合スコア8

さくらのVPS

さくらのVPSは、さくらインターネット社が提供するVPS(仮想専用サーバー)です。高速なSSDの選択や複数台構成も可能。利用者に応じた柔軟なプランが用意されています。大規模システムにも対応可能なスケーラビリティを備えたホスティングサービスです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/11/20 13:43

編集2020/11/22 02:17

前提・実現したいこと

Ratchet「PHPライブラリ」を使用し、「さくらのVPS」環境下に、WebSocketを実現しようとしております。
https://github.com/ginjake/php_chat
上記のサイトを参考にし、SSL化を行うまでは、js側のws接続にてWebSocket通信が正常に起動していることを確認いたしました。

SSL化を行った後、HTTPS環境下から、対象のWSサーバーへ通信した際に、

Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

というコンソールエラーが表示されたため、js側のwss接続方法へ変更いたしました。

wss接続へ変更した際に次は、

failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

js変更内容
×'ws://domain.xyz:8080/room/id/';
○'wss://domain.xyz:8080/room/id/';

Apacheの設定が正しく行えていないことが原因でしょうか?
サーバーやApacheについての知識不足のため、ご教示いただけますと幸いです。

js

1var requestUrl = 'wss://domain.xyz:8080/room/id/'; 2(function($){ 3 var settings = {}; 4 var methods = { 5 init : function( options ) { 6 settings = $.extend({ 7 'uri' : requestUrl, 8 'conn' : null 9 }, options); 10 $(this).chat('connect'); 11 }, 12 connect : function () { 13 if (settings['conn'] == null) { 14 settings['conn'] = new WebSocket(settings['uri']); 15 settings['conn'].onopen = methods['onOpen']; 16 settings['conn'].onmessage = methods['onSend']; 17 settings['conn'].onclose = methods['onClose']; 18 settings['conn'].onerror = methods['onError']; 19 } 20 }, 21 onOpen : function ( event ) { 22 console.log('サーバーに接続'); 23 }, 24 onSend : function (event) { 25 if (event && event.data) { 26 $(this).chat('drawText',event.data); 27 } 28 }, 29 onError : function(event) { 30 console.log('エラー発生'); 31 }, 32 onClose : function(event) { 33 console.log('サーバーと切断'); 34 settings['conn'] = null; 35 setTimeout(methods['connect'], 1000); 36 }, 37 drawText : function (message) { 38 $('#price').text(message); 39 }, 40 parseJson : function(data){ 41 returnJson = {}; 42 for (idx = 0; idx < data.length; idx++) { 43 returnJson[data[idx].name] = data[idx].value 44 } 45 return returnJson; 46 }, 47 }; // end of methods 48 49 $.fn.chat = function( method ) { 50 if ( methods[method] ) { 51 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); 52 } else if ( typeof method === 'object' || ! method ) { 53 return methods.init.apply( this, arguments ); 54 } else { 55 $.error( 'Method ' + method + ' does not exist' ); 56 } 57 } // end of function 58})( jQuery );

Ratchetディレクトリ構成

Ratchet(root directory) ├bin |└server.php ├src |└chat | └chat.php ├vendor ├composer.json ├composer.lock └index.php

###server.php

php

1<?php 2use Ratchet\Server\IoServer; 3use chat\Chat; 4use Ratchet\Http\HttpServer; 5use Ratchet\WebSocket\WsServer; 6 7require dirname ( __DIR__ ) . '/vendor/autoload.php'; 8 9$server = IoServer::factory ( new HttpServer( new WsServer( new Chat () ) ), 8080 ); 10 11$server->run ();

###chat.php

php

1<?php 2namespace MyApp; 3use Ratchet\MessageComponentInterface; 4use Ratchet\ConnectionInterface; 5 6class Chat implements MessageComponentInterface { 7 protected $clients; 8 9 public function __construct() { 10 $this->clients = new \SplObjectStorage; 11 } 12 13 public function onOpen(ConnectionInterface $conn) { 14 // Store the new connection to send messages to later 15 $this->clients->attach($conn); 16 17 $conn_param = $this->parse_url_param($conn->httpRequest->getRequestTarget()); 18 //個人チャットを開いたときの処理 19 if ($conn_param["mode"] == "private") { 20 //ログイン状態を確認してクライアントに送信 21 $this->login_status_send($conn, $conn_param, 'online'); 22 } 23 24 echo "New connection! ({$conn->resourceId})\n"; 25 } 26 27 public function onMessage(ConnectionInterface $from, $msg) { 28 29 $from_param = $this->parse_url_param($from->httpRequest->getRequestTarget()); 30 31 if ($from_param["mode"] == "room") { 32 foreach ($this->clients as $client) { 33 //同じルームの人対象に送信。 34 $client_param = $this->parse_url_param($client->httpRequest->getRequestTarget()); 35 if ($from_param["room"] === $client_param["room"]) { 36 $client->send($msg); 37 } 38 } 39 } 40 41 if ($from_param["mode"] == "private") { 42 43 $send_comp_flag = 0; 44 foreach ($this->clients as $client) { 45 //対象を指定 46 $client_param = $this->parse_url_param($client->httpRequest->getRequestTarget()); 47 if ($from_param["target"] === $client_param["myself"]) { 48 if ($from_param["myself"] === $client_param["target"]) { 49 $client->send($msg); 50 $send_comp_flag = 1; 51 } 52 } 53 } 54 if ($send_comp_flag) { 55 foreach ($this->clients as $client) { 56 //自分に送信 57 $client_param = $this->parse_url_param($client->httpRequest->getRequestTarget()); 58 if ($from_param["target"] === $client_param["target"]) { 59 if ($from_param["myself"] === $client_param["myself"]) { 60 $client->send($msg); 61 } 62 } 63 } 64 } 65 if ($send_comp_flag == 0) { 66 $error["type"] = 'error'; 67 $error["code"] = '1'; 68 $error["detail"] = '相手がエラーのため送信に失敗しました'; 69 $from->send(json_encode($error)); 70 } 71 } 72 } 73 74 public function onClose(ConnectionInterface $conn) { 75 // The connection is closed, remove it, as we can no longer send it messages 76 $conn_param = $this->parse_url_param($conn->httpRequest->getRequestTarget()); 77 78 if ($conn_param["mode"] == "private") {// 個人チャットの場合、退室を相手に伝える 79 //ログイン状態を確認してクライアントに送信 80 $this->login_status_send($conn, $conn_param, 'offline'); 81 } 82 83 $this->clients->detach($conn); 84 echo "Connection {$conn->resourceId} has disconnected\n"; 85 } 86 87 public function onError(ConnectionInterface $conn, \Exception $e) { 88 echo "An error has occurred: {$e->getMessage()}\n"; 89 $conn_param = $this->parse_url_param($conn->httpRequest->getRequestTarget()); 90 91 if ($conn_param["mode"] == "private") {// 個人チャットの場合、退室を相手に伝える 92 //ログイン状態を確認してクライアントに送信 93 $this->login_status_send($conn, $conn_param, 'offline'); 94 } 95 $conn->close(); 96 } 97 98 public function login_status_send(&$conn, $connect_param, $send_param) { 99 foreach ($this->clients as $client) { 100 $client_param = $this->parse_url_param($client->httpRequest->getRequestTarget()); 101 if ($connect_param["target"] === $client_param["myself"]) { 102 if ($connect_param["myself"] === $client_param["target"]) {//互いにオンラインである 103 104 $msg["type"] = "info"; 105 $msg["status"] = $send_param; 106 //既存入室者に、相手がオンラインになったことを伝える 107 $client->send(json_encode($msg)); 108 //新規入室者に、相手が既にオンラインであることを伝える 109 $conn->send(json_encode($msg)); 110 } 111 } 112 } 113 } 114 115 public function parse_url_param($string) { 116 $query = str_replace("/?", "", $string); 117 parse_str($query, $return_param); 118 return $return_param; 119 } 120}

開発環境

# OS: $cat /etc/redhat-release CentOS Linux release 7.8.2003 (Core) # Apache $httpd -v Server version: Apache/2.4.6 (CentOS) Server built: Apr 2 2020 13:13:23 # PHP $php -v PHP 7.3.24 (cli) (built: Oct 27 2020 11:01:59) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.24, Copyright (c) 1998-2018 Zend Technologies

httpd.conf

httpd

1<VirtualHost *:443> 2# ServerName ipAddress:8080 3 ServerName domain.xyz:443 4 ProxyRequests Off 5<Location /> 6 #Order allow, deny 7 Require all granted 8</Location> 9 <Proxy *> 10 #Order deny,allow 11 Require all granted 12 </Proxy> 13 ProxyPreserveHost On 14 ProxyPass "/ws/" "ws://domain.com:8080/" 15 ProxyPassReverse "/ws/" "ws://domain.com:8080/" 16 ProxyStatus On 17</VirtualHost>

vhost.conf

vhost

1<IfModule mod_ssl.c> 2<VirtualHost *:443> 3 SSLEngine on 4 SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key 5 SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt 6 SSLCertificateChainFile /etc/httpd/conf/ssl.crt/internal.crt 7 8 DocumentRoot /var/www/html/ 9 ServerName domain.com 10 ServerAlias domain.com 11 SSLStrictSNIVHostCheck off 12 13 <Directory "/var/www/html/"> 14 Options FollowSymLinks 15 AllowOverride All 16 php_flag display_errors On 17 Require all granted 18 </Directory> 19 20 SSLProxyEngine On 21 RewriteEngine On 22 23 # When Upgrade:websocket header is present, redirect to ws 24 # Using NC flag (case-insensitive) as some browsers will pass Websocket 25 RewriteCond %{HTTP:Upgrade} =websocket [NC] 26 RewriteRule / wss://domain:8080/$1 [P,L] 27 28 # All other requests go to http 29 ProxyPass "/" "https://domain.com" 30</VirtualHost> 31</IfModule>

ssl.conf

conf

1Listen 443 2SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog 3SSLSessionCache shmcb:/run/httpd/sslcache(512000) 4SSLSessionCacheTimeout 300 5SSLRandomSeed startup file:/dev/urandom 256 6SSLRandomSeed connect builtin 7SSLCryptoDevice builtin 8SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt 9SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key 10SSLCertificateChainFile /etc/httpd/conf/ssl.crt/internal.crt 11SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

一旦、クローズいたします。

対応内容としては、一時的な処置ではありますが443ポートから、対象のRatchetサーバーへの接続を行う設定にいたしました。

投稿2021/02/22 08:52

fenjapa

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問