3

我知道在处理 websockets 时,我不能使用 session。playframework 2 websocket 聊天示例将用户名添加到 url,但是如果我有一个已经登录的用户并且我不想通过 url 传递他的用户名,还有另一种方法可以从内部获取用户登录凭据websocket 请求?

到目前为止,这是我尝试过的:请求页面,我将从那里连接到套接字:

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
}

我打印出来的所有内容都是空我做错了什么?

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 示例(它不在 master 分支上)。

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)
  }

}

这确实由 playframework 保护

于 2013-08-29T15:39:12.423 回答
1

websocket连接不是Http。第一个握手请求看起来有点像 http,但确实包含其他字段。这就是为什么你不能在 websocket 请求中添加你的 http cookie。

来自维基百科:

握手类似于 HTTP,因此服务器可以在同一端口上处理 HTTP 连接和 WebSocket 连接。但是,涉及的特定字段以及握手之后的内容不符合 HTTP 协议。

如果您不想要用户名,您可以在 url 中使用令牌/会话 ID,或者,如果在启动 websocket 连接之前无法实现登录/密码检索,请实现您自己的登录/密码检索方法通过 websocket 通信(例如服务器以特定格式请求登录/密码,客户端 js 做出反应,收集并发送回服务器)。

于 2013-06-16T19:15:23.483 回答