eclipse+activatorでデバッグをWindows環境で行う

PlayFramework2.3から従来のplayコマンドではなくactivatorコマンドに変更となりました。それに伴いデバッグ方法も変わってしまったので、以下に書き留めておきます

環境

  • Windows8.1
  • eclipse 4.3
  • scala2.11
  • jdk1.7

設定

%UserProfile%\.activator\activatorconfig.txtにファイルを作成します。通常ですと、

になるかと思います

このファイルに以下を記述します。addressはデバッグ用のポートなので開いているポートならばなんでも構いません。

実行

プロジェクトのフォルダにコマンドラインからアクセスし、activatorで起動します。8000番ポートでデバッグ用にポートが開いているのがわかります

次にEclipseからプロジェクトを右クリックし、DebugConfigurationからRemoteJavaApplicationをダブルクリックします。ポート番号8000を確認しScalaDebugger(SocketAttach)を選択。起動します。ブラウザを開いてアプリケーションにアクセスすれば、ブレークポイントでデバッグ可能となります。

設定はこの辺りに詳しく書いています

http://stackoverflow.com/questions/19473941/cant-debug-with-typesafe-activator

PlayFramework+EclipseでViews.htmlエラー

いつも忘れるのでメモ

PlayFrameworkをEclipseで開発しているとこのエラーが必ず出ます

これの解決方法ですがプロジェクトのプロパティからJavaBuildPathを選択し、LibrariesタブからAddClassFolderで targetーscala-2.11ーclass_managedを追加

F5を押してリフレッシュすれば治ります

これが赤いままだとUnitテストでClassNotFoundエラーが出ます

batikをPlayFrameworkで使う

batikとはSVGからPDFやPNG等へ変換するすごーく便利なJavaのライブラリです。これをPlayframeworkでWebアプリとして構築してみました

準備

batickで使用するJarファイルをダウンロードしてきます。

http://mvnrepository.com/artifact/batik

この辺りから落としてくれば十分です

batik-anim.jar

batik-svgpp.jar

batik-awt-util.jar

batik-swing.jar

batik-bridge.jar

batik-transcoder.jar

batik-codec.jar

batik-ttf2svg.jar

batik-css.jar

batik-util.jar

batik-dom.jar

batik-xml.jar

batik-ext-1.6-1.jar

batik.jar

batik-ext.jar

batik-extension.jar

batik-gui-util.jar

batik-gvt.jar

batik-parser.jar

batik-rasterizer.jar

batik-script.jar

batik-slideshow.jar

batik-squiggle.jar

batik-svg-dom.jar

batik-svggen.jar

pdf-transcoder.jar

js.jar

w3c.jar

気がついたらこれだけダウンロードしていました。全部いるのでしょうか?

今回はPDFとJPEGとPNGをパラメタで分けて出力します

PlayFramework+Redis+websocketでプッシュ配信(データ圧縮編)

Websocketに最近はまっています。

前回プッシュ配信をRedisのPub/Subを用いて実現した訳ですが、データ量が増えてくるとどうしても配信するデータを圧縮したくなります。

特にAWSなんかだと、従量課金となっていますので、データ転送量は少なければ少ないほど○

Websocket自体はまだデータの圧縮はサポートされていないとのことですので、自前でデータの圧縮伸長を実装してみました。

また、それだけではつまらないので、Reidsにチャンネルを作成し、ReidsのチャンネルごとにPub/Subする仕組みを入れています

図解するとちょっとわかりにくいですがこんな感じ

User別に作成したActorと、ユーザが選択したチャンネル(code1,code2,code3)別に作成したActorを別々に作成し、チャンネルがReidsから更新された際には、購読しているUserのActorへ更新をかけるという感じです

こうすることにより、チャンネル数がユーザ数より圧倒的に少ない場合には、Reidsに対するコネクションも削減でき、効率が良くなります。

  • route

  • Compress.scala

データ圧縮用に作成します。String型をZIP圧縮し、BASE64でエンコードします

  • UserActor.scala

  • Javascriptで解凍

JavaScriptでZIP解凍、Base64でコードするために↓からinfrate.js,base64.js,utf.jsなどをダウンロードしておきます。

http://www.onicos.com/staff/iz/amuse/javascript/expert/

サンプルの一式は以下においておきました

https://github.com/anagotan/play_websocket_compressed

PlayFramework+Redis+websocketでプッシュ配信を作成してみる

Websocketを使ったサンプルだとチャットが多いのですが、実際にはチャットのアプリを作ることはあまり有りません。

どちらかというとサーバ側から配信するというような用途が多いのではないでしょうか?

PlayframeworkのサンプルにはWebsocketを使ったサンプルが付属しています。

これを改造してサーバ側から配信できるように改造してみました

  • 環境
    • MacOS10.9
    • jdk1.7
    • playframework2.2
    • redis2.8.4
    • scala2.10
  • playframeworkのチャットサンプル

brewでインストールした場合にはこちらに入っているので、作業エリアにコピーしておきます

/usr/local/Cellar/play/2.2.1/libexec/samples/scala/websocket-chat/

  • unicast

一斉配信したい場合にはサンプルで採用されているbroadcastをそのまま使用してもいいのですが、今回は一対一通信で配信したいのでunicastを使用します。サンプルはこちらを参考にしました。

http://satoshi-m8a.github.io/blog/2013/05/18/scala-concurrent-unicast/

  • build.sbt

scalaからredisに接続するためにはscala-redisライブラリを使用します。そのためbuild.sbtに以下を記述します

  • conf/logger.xml

ログ出力用に追加します

  • conf/application.conf

redisの接続先をconfに書いておきます

  • models/ChatRoom.scala

モデルをscala-redisのテストコードを参考に修正します

これで準備完了

  • 実行

play runで実行し、ユーザ名部分にカンマ区切りでキーを入力します。このキーはカンマ区切りで複数入力可能で、このキーがredisのキーとなります。

画面が起動したら、a,b でログインしてみます

その後Reidsのコマンドで値を送ってみます

画面にa test が表示されます

PlayFramework2.1でセッションタイムアウトを作ってみた

PlayFrameworkのセッションはCookieになります。ブラウザを閉じるまで有効なので、従来のservletなどで実現してきたsessionの観念はありません。

これが意外と困ってしまうので(タイムアウトした際にログアウトさせるなど)Cookieに時間を持たせることによりにたようなものを実装してみました

routes

controllers.Application.scala

helper.Login.scala

本来ならばログインIDとパスワードとつきあわせてチェックするのですがとりあえず必ずOKになるように

helper.Session.scala

クッキーに保存した時刻と現在時刻を比較し、ログアウトの判定

views.index.scala.html

views.login.scala.html

ログイン後1分放置するとログイン画面に戻ります

Slick+PlayFramework2.1でDBアクセスしjsonで出力

実際の業務では、サンプルなどでよく見かける、データの作成、更新、参照、削除という流れは実際ではあまりなく、既にあるデータを参照するだけとか祖いうのが多いかと思います。

前回までで、既存データベースに入っているデータを取得することができたので、JSON形式で出力してみます。

GSON

sjsonやPlay標準のJSONなど何種類かあるようですが、ちょっと試したところうまくいかなかったので、GSONを使用することにしました。

あらかじめGSONをダウンロードしておきeclipseのパスに追加しておきます。

http://code.google.com/p/google-gson/

mysql

application.conf

routes

controllers.Data.scala

models.Price.scala

views.json.scala.html

jsonp用

Slick+PlayFramework2.1でDBアクセス#2

既存のデータベースにアクセスしてみます。

DBのコネクションをPlayFrameworkから与えることでモデル側でコネクションを作成しません

MySQL

application.conf

routes

controllers.Application.scala

models.Price.scala

views.index.scala.html

Slick+PlayFramework2でデータベースアクセス

ScalaでPlayFrameworkを使う場合にDBアクセスにはanormとslickがあるようです。

slickはscalaQueryと呼ばれていたものが進化した模様。

scala2.9まではscalaQuery,それ以降はslickらしいです

http://d.hatena.ne.jp/tototoshi/20121204/1354615421

Build.scalaに必要なモジュールを書いてインストールするのが一般的らしいですが、うまくいかなかったので手動インストールで作成してみます。

slick

https://github.com/freekh/play-slick

からZIPでダウンロードし解凍

play-slick

プラグインなのでこちらも入れます

https://github.com/freekh/play-slick

プロジェクト作成

Eclipse

  • eclipseの既存プロジェクトの読み込みで読み込む
  • プロジェクトのプロパティからslick_2.10-1.0.1.jar、play-slick_2.10-0.3.3-SNAPSHOT.jarのライブラリを追加

PlayFramework

http://takashima0411.hatenablog.com/entry/2012/11/28/231817

こちらの方のサンプルをそのままいただきました

Application.scala

Task.scala

Global.scala

index.scala.html

routes

application.conf

これでとりあえず動きます

PlayFramework2.1で既存のMySQLにつないでみる

ちょっと悩んだのでメモ

PlayFrameworkで既存のMySQLにつなぐためには

テーブルはこれ

まずモデル

application.conf

これを使って、ViewとControllerにつなげれやればおっけー