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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

JavaScript

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

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

4781閲覧

グローバルIPによる接続とローカルIPでの接続によるwebサーバでの挙動が異なる[ROS,javascript]

masabs

総合スコア13

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

JavaScript

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

ネットワーク

ネットワークとは、複数のコンピューター間を接続する技術です。インターネットが最も主流なネットワークの形態で、TCP/IP・HTTP・DNSなどの様々なプロトコルや、ルータやサーバーなどの様々な機器の上に成り立っています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2020/07/03 09:07

編集2020/07/04 17:36

前提・実現したいこと

ROSのroswwwを使ったwebサーバで、サーバ上のHTMLファイル内にjavascriptでROSへの接続を記述しています。
ROSのサーバを持つ端末のLAN外にあるクライアントからこのHTMLにアクセスして、ROSの指令を出せるようにしたいです。

発生している問題・エラーメッセージ

まず、サーバ端末とクライアント端末を同一LAN内に配置してHTMLにアクセスしたところ、所望の動作が得られました。
----  サーバ端末上でROSのサーバ(roswww)とサーバとROSのブリッジ(rosbridge_server)を起動
----  クライアント端末からChromeでhttp://192.168.xxx.xxx:8085/WorkSpace/example.htmlに接続
----  ChromeにHTMLファイルの内容が表示され、javascriptによるROSへの接続が成功。
----  (接続できた際のメッセージ"Connect"がChrome上に表示される)

次に、クライアント端末をサーバ端末のLANから外し、サーバ端末のグローバルIPを指定してHTMLにアクセスしたところ、
HTMLへのアクセスはできましたが、HTMLファイル内のjavascriptによるROSへの接続ができませんでした。
----  サーバ端末のLANのインターネットルータのポートマッピングを設定
----   [WANアドレス:xxx.xxx.xxx.xxx,ポート 80 → LANアドレス:192.168.xxx.xxx,ポート8085]
----  上記と同様に、サーバ端末上でroswwwとrosbridge_serverを起動
----  クライアント端末からChromeでhttp://xxx.xxx.xxx.xxx/WorkSpace/example.htmlに接続
----  ChromeにHTMLファイルの内容が表示されるが、javascriptによるROSへの接続が失敗。
----  (接続できなかった際のメッセージ"Close"がChrome上に表示される。)

LAN経由とグローバルネットワーク経由では、同じHTMLにアクセスしても何か動作に異なることがあるのでしょうか?
どの部分を調べていけばよいのか分からず困っています。

該当のソースコード

HTML

1<html lang="ja"> 2<head> 3<meta charset="UTF-8"> 4<title>ros sample</title> 5<script src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script> 6<script src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script> 7</head> 8<body> 9 <h3>rosjs example</h3> 10 <p>status: <label id="state">Disconnect</label></p> 11 12<script> 13// rosbridgeと接続 14const ros = new ROSLIB.Ros({ 15 url : ('ws://' + location.hostname + ':9090') 16}); 17// 接続時のコールバック 18ros.on('connection', function() { 19 console.log('Connected to websocket server.'); 20 document.getElementById('state').innerHTML = "Connect"; 21}); 22// エラー時のコールバック 23ros.on('error', function(error) { 24 console.log('Error connecting to websocket server: ', error); 25 document.getElementById('state').innerHTML = "Disconnect"; 26}); 27// 切断時のコールバック 28ros.on('close', function() { 29 console.log('Connection to websocket server closed.'); 30 document.getElementById('state').innerHTML = "Close"; 31}); 32 33</script> 34</body>

試したこと

■9090番のポートマッピング →マッピング後も接続できない状況のまま変わらず。
ルータのポートマッピング設定

■クライアント側ブラウザのコンソールのエラーを確認。
WebSocketのエラー
roslib.min.js:1
WebSocket connection to 'ws://XXX.XXX.XXX.XXX:9090/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
d.connect @ roslib.min.js:1
d @ roslib.min.js:1
(anonymous) @ connect.html:14

■('ws://' + location.hostname + ':9090') → 'ws://192.168.100.110:9090/'(サーバのアドレスを指定)
同様のエラー
WebSocket connection to 'ws://192.168.100.110:9090/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
d.connect @ roslib.min.js:1
d @ roslib.min.js:1
(anonymous) @ connect.html:14

補足情報(FW/ツールのバージョンなど)

サーバ側端末(ROSの搭載端末): Jetson nano (Ubuntu 18.04)

クライアント側端末:Windows10

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

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

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

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

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

guest

回答2

0

url : ('ws://' + location.hostname + ':9090')

で、9090番ポートにwebsocket接続に行っているようなので、9090番ポートも
WAN側に見せれば動くと思います。

投稿2020/07/03 11:37

YakumoSaki

総合スコア2027

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

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

masabs

2020/07/03 19:18

ご回答ありがとうございます。そのときのWAN側のポートはどのように指定すればよいのでしょうか?websocketのデフォルト80番だと他のマッピングと競合してしまうのですが、、、 知識が浅く申し訳ありません。自身で調べてはみましたが、やり方が分かりませんでした。再度ご教授いただけると大変ありがたいです。
YakumoSaki

2020/07/04 14:35

WAN側のアドレスの 9090番をそのままLAN側のIPアドレスの9090番ポートにマップすればよいかと思います。 都合、 (ルーターに) WAN側のアドレス:80 → LAN側のアドレス:8085 WAN側のアドレス:9090 → LAN側のアドレス:9090 の2つのマッピングを作ることになります。
masabs

2020/07/04 15:34

ありがとうございます。教えていただいた内容を試しましたが、まだ問題があるようで、繋がりませんでした。クライアント側ブラウザのコンソールを確認しましたが、やはり指摘いただいてる部分のWebsocket接続でエラーが出ています。 もし他に確かめるべきことやデバッグの方法など思いつくことがございましたら、お手数ですが再度ご教授いただけると大変ありがたいです。 試したことを追記しました。
masabs

2020/07/07 02:06

解決できました。ありがとうございました。
guest

0

自己解決

###サーバ側にリバースプロキシを導入することで解決しました。

WebサーバのHTMLにクライアント側からアクセスしてwebsocketを発行させる際、HTMLにアクセスするのと同じWAN側80番による接続となるため、ルータのポートマッピング機能でLAN側9090番にwebsocketを通せないことが問題でした。(httpアクセス用のWAN80番→LAN8085番のマッピングと重複してしまう)

websocket発行の際に80番と別のWAN側ポートを指定できればそのポートをマッピングすれば良いと思うのですが、このあたり十分理解できていないのですがクライアント側ブラウザのChromeからではとりあえず無理そうでした。

そこで、ルータのマッピングによる方法ではなく、サーバ側にNginxによるリバースプロキシを設定し、
WAN側80番のhttpをLAN側8085番、WAN側80番のwebsocketをLAN側9090番に転送するようにし、無事接続できるようになりました。

つまり、自分の元の疑問である「グローバルIPによる接続とローカルIPでの接続によるwebサーバでの挙動が異なる」については、グローバルIPで接続する場合、httpもwebsocketもWAN側80番のポートを通る(80番以外だと通らない。これは自分の環境のみの制約?webブラウザの制約?)。ローカルで自由にポートアクセスできるときと比べて、ルータ通過後にリバースプロキシで別のポートに振り分けるなどの必要が出てくる、ということでした。

以下のページを参考にさせていただきました。
nginx(1.4.3)のproxyでWebとWebSocketのポート共有。SSL対応

server.conf

1 upstream any_web { 2 ip_hash; 3 server ローカルIP:8085 weight=5; 4 } 5 6 upstream any_websocket { 7 ip_hash; 8 server ローカルIP:9090; 9 } 10 11 server { 12 listen 80; 13 14 location /ws/ { 15 proxy_pass http://any_websocket; 16 proxy_http_version 1.1; 17 proxy_set_header Upgrade $http_upgrade; 18 proxy_set_header Connection "upgrade"; 19 proxy_set_header Host $host; 20 } 21 location / { 22 proxy_pass http://any_web; 23 proxy_redirect default; 24 } 25 }

また、今回のwebsocketの接続先はROSのノードになっていて、実はそちら側の制約で上記のコードでもまだ不十分でした。上記をSSLを使ったhttpsとwssでの接続に書き換えて、やっと最終的な接続ができるようになりました。

投稿2020/07/07 02:48

masabs

総合スコア13

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問