3

Websocket を扱う場合、session を使用できないことを理解しています。playframework 2 websocket チャットの例では、ユーザー名を URL に追加しますが、既にログインしているユーザーがいて、URL を介してユーザー名を渡したくない場合は、ユーザーのログイン資格情報を内部から取得する別の方法がありますか?ウェブソケットリクエスト?

これが私がこれまでに試したことです: ソケットに接続する場所からのリクエストページ:

public static Result index(){
    session("username", "mike")
    return ok(indexpage.render());
}

Websocket 部分は次のとおりです。

public static Websocket<JsonNode> chat(){
    System.out.println(session("username"));    
    ....all the websocket stuff
}

印刷されたものはすべてnullです。何が間違っていますか?

4

3 に答える 3

3

セッションにアクセスできます:

package controllers

import play.api._
import play.api.mvc._
import play.api.libs.iteratee._

object Application extends Controller {
  def index = Action {
    Ok(views.html.index()).withSession("connected" -> "user@gmail.com")
  }

  //I used for views.html.index the html markup from http://www.websocket.org/echo.html
  def wstest = WebSocket.using[String] { request =>

    val in = Iteratee.consume[String]()

    val username = request.session.get("connected").getOrElse("missing username")

    val out = Enumerator("Hello " + username) //puts  Hello user@gmail.com on the screen

    (in, out)
  }
}

さて、Java (コントローラー内のメソッド) の場合:

public static WebSocket<String> chat(){
    final Http.Session session = session();
    final String name = session("username");//better version

    return new WebSocket<String>() {
        public void onReady(WebSocket.In<String> in, WebSocket.Out<String> out) {
            in.onMessage(new F.Callback<String>() {
                public void invoke(String event) {
                    System.out.println(event);
                }
            });

            in.onClose(new F.Callback0() {
                public void invoke() {
                    System.out.println("Disconnected");
                }
            });

            out.write("Hello " + session.get("username"));
            out.write("Hello " + name);
        }
    };
}

Websocket の作成で http コンテキストに直接アクセスすることはできないようですが、Cookie からのセッションまたはより良いデータを定数に保存し、それを WebSocket インスタンスの作成で使用できます。

テストhttps://github.com/schleichardt/stackoverflow-answers/tree/so12879547を含むJavaの例をアップロードしました(マスターブランチにはありません)。

PS: WebSocket の作成では機能しませんでした:

Http.Context.current().session().get("username")
于 2012-10-14T07:52:00.387 に答える
1

HTTP ハンドシェイクとして初期化されているため、Session へのアクセスが許可されます。セッションに貼り付けることで、認証されたアクションからユーザー名キー、値を定義できます。

Redirect(.....).withSession("login" -> user)

その後:

object WebsocketController extends Controller {

  def wsConnection = WebSocket.async[JsValue] { request =>

    val userOption: Option[String] = request.session.get("login")

    //do your credential check or login ....

    (in, out)
  }

}

これは確かにプレイフレームワークによって保護されています

于 2013-08-29T15:39:12.423 に答える
1

Websocket 接続は Http ではありません。最初のハンドシェイク リクエストは http に少し似ていますが、他のフィールドが含まれています。そのため、WebSocket リクエストに http Cookie を追加することはできません。

ウィキペディアから:

ハンドシェイクは HTTP に似ているため、サーバーは同じポートで HTTP 接続と WebSocket 接続を処理できます。ただし、関連する特定のフィールドと、ハンドシェイクの後に続くものは、HTTP プロトコルに準拠していません。

そこにユーザー名が必要ない場合は、URL でトークン/セッション ID を使用できます。または、websocket 接続を開始する前にログイン/パスワード取得を実装できない場合は、ログイン/パスワード取得の独自の方法を実装します。 Websocket通信を介して(たとえば、サーバーが特定の形式でlogin/pwを要求し、クライアントjsが反応して収集し、サーバーに送り返します)。

于 2013-06-16T19:15:23.483 に答える