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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

5473閲覧

Ratchetを使ったチャットシステムでのsubscribe登録機能について

nagasa

総合スコア35

WebSocket

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/03/20 11:18

環境
php5.6
ratchet:v0.3.6

PHP版のRatchetを用いて、チャットシステムの勉強をしています。
下記のチュートリアルの内容を組み合わせて、チャットする各ユーザーを
RoomIDのようなものでチャット部屋を分けて、その中でのみメッセージを
配信できるようにしたいと考えています。
(zeroMQを利用してtopicにRoomIDを割り当てるという方法を試しています。)
http://socketo.me/docs/hello-world
http://socketo.me/docs/push

そこでchat-serverは下記の通りのコードにしています。
chat-server.php

<?php use Ratchet\Server\IoServer; use Ratchet\Http\HttpServer; use Ratchet\WebSocket\WsServer; use MyApp\Chat; require dirname(__DIR__) . '/vendor/autoload.php'; $server = IoServer::factory( new HttpServer( new WsServer( new Chat() ) ), 8080 ); $server->run();

chat.php

<?php namespace MyApp; use Ratchet\MessageComponentInterface; use Ratchet\ConnectionInterface; use Ratchet\ComponentInterface; class Chat implements MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { // Store the new connection to send messages to later $this->clients->attach($conn); echo "New connection! ({$conn->resourceId})\n"; } //この部分はチュートリアルのままで、今後修正予定です。 public function onMessage(ConnectionInterface $from, $msg) { $numRecv = count($this->clients) - 1; echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n" , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); foreach ($this->clients as $client) { if ($from !== $client) { // The sender is not the receiver, send to each client connected $client->send($msg); } } } //ここはチュートリアルから追加しています。 public function onSubscribe(ConnectionInterface $conn, $topic) { if (!array_key_exists($topic->getId(), $this->subscribedTopics)) { $this->subscribedTopics[$topic->getId()] = $topic; } } //ここはチュートリアルから追加しています。 public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) { $json = json_decode($event); $topic->broadcast(Security::htmlentities($json->input)); } public function onClose(ConnectionInterface $conn) { // The connection is closed, remove it, as we can no longer send it messages $this->clients->detach($conn); echo "Connection {$conn->resourceId} has disconnected\n"; } public function onError(ConnectionInterface $conn, \Exception $e) { echo "An error has occurred: {$e->getMessage()}\n"; $conn->close(); } }

クライアントはまず、webのページに入った直後にchat-serverに接続してtopicにRoomIDを割り当てたいと考えています。
chat.html

<script src="http://autobahn.s3.amazonaws.com/js/autobahn.min.js"></script> <script> var conn = new ab.Session('ws://localhost:8080', function() { conn.subscribe('RoomID', function(topic, data) { // This is where you would add the new article to the DOM (beyond the scope of this tutorial) console.log('New article published to category "' + topic + '" : ' + data.title); }); }, function() { console.warn('WebSocket connection closed'); }, {'skipSubprotocolCheck': true} ); </script>

しかし、下記のようなエラーがクライアント側で生じて、一旦接続しますが、すぐに切られてしまいます。
WebSocket connection to 'ws://localhost:8080/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received

autobahn.min.js:62

対処方法がわからず、アドバイス頂きたくよろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

お使いのPHPライブラリ(Ratchet)とJSライブラリ(AutobahnJS)の扱っているプロトコル(WAMP)のバージョンが違うためにハンドシェイクに失敗してるようにみえます。

RatchetがWAMP v1に、AutobahnJSがWAMP v2に準拠している。

Ratchetの公式ページにはWAMPのバージョンが記載されてませんでしたが(ちらっと覗いただけなのでどこかに書いてあるかも)、
以下のIssueでRatchetの作者(っぽい人)がロードマップからWAMPv2のサポートを取り下げたと言ってますので、おそらくRatchetはWAMPv1準拠だと思われます。

Support WAMPv2 · Issue #168 · ratchetphp/Ratchet
https://github.com/ratchetphp/Ratchet/issues/168#issuecomment-55339203

I've decided to remove WAMPv2 support from the roadmap, at least for the time being.

対して、AutobahnJSは公式ページにWAMPv2に準拠してると記載ありました。

Autobahn|JS — AutobahnJS 0.9.4 documentation
http://autobahn.ws/js/

Features
supports WAMP v2, works with any WAMP server

ですので、RatchetとAutobahnJSのプロトコルverを合わせられれば解決できそうですが(AutobahnJSの古いバージョンを探すとか?)、
特にPHPに拘る理由がなく、チャットの仕組みを勉強されたいとのことでしたら、
まずはNodeJSなどで試されるのが手軽で良いかもしれません。

「NodeJS チャット」で検索すると沢山ヒットします。

根本的な解決ではなくてすみません。

投稿2017/03/20 12:12

編集2017/03/20 12:14
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

nagasa

2017/03/20 12:23

回答ありがとうございます。内容確認いたします。
nagasa

2017/03/20 12:33

また、node.jsとrachetは悩んだ挙句、両睨みで対応できるようにしたいと考えていまして、まずは、rachetでいこうかと思った次第です。現在、メインのシステムはcakephp3を使っていまして、連携面で同じphpのrachetもいいかなと思ったり、node.jsは処理性能が良さそうだから、やっぱり本命はこちらかなと思ったり迷っています。
退会済みユーザー

退会済みユーザー

2017/03/20 12:52 編集

なるほど。勝手に学習用途と思ってましたが、それなりに実践的なシステムを組まれてるようですね。 では、Ratchetに代わるPHPライブラリを探してみるのも手ですね。 上記GitHub IssueでRatchetの作者(っぽい人)が言及してるPHPライブラリがこちらなのですが、 Autobahnとも相性良さそうなこと書いてますので、選択肢の一つとして提案しておきますね。 voryx/Thruway: PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging https://github.com/voryx/Thruway
nagasa

2017/03/20 13:15

ありがとうございます。確認します。今、下記の古バージョンを試しました。http://autobahn.ws/js/reference_wampv1.html minimized and gzipped版は「Uncaught ReferenceError: ab is not defined」というエラーがでて クライアント側のchat.html のvar conn = new ab.Session('ws://localhost:8080',というところで止まってしまうようです。only minimized版とDevelopment版は当初のエラーが出てしまいました。
nagasa

2017/03/21 12:29

内容確認しまして、ご紹介のvoryx/Thruwayを試しまして、目的のsubscribe機能が実現しました。ありがとうございます。当初の方針と変わりましたが、ベストアンサーにいたします。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問