Playframework 2,Websockets 和 Session
Posted
技术标签:
【中文标题】Playframework 2,Websockets 和 Session【英文标题】:Playframework 2, Websockets and Session 【发布时间】:2012-10-14 05:24:25 【问题描述】:我了解在处理 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
我打印出来的都是空的 我做错了什么?
【问题讨论】:
【参考方案1】:您可以访问会话:
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/***-answers/tree/so12879547 的 Java 示例(它不在 master 分支上)。
PS: 这在 WebSocket 创建中不起作用:
Http.Context.current().session().get("username")
【讨论】:
感谢您的回复,不幸的是我正在使用java,忘记提及了。这是我目前尝试过的,无法添加代码来评论,我会回复 我已经尝试了你的建议,添加了“最终的 Http.Session session = session()”,但是当我尝试从会话中提取用户名时,我仍然得到 null。非常感谢您在这方面的帮助。 如果你尝试'final String name = session("username");'在构造 WebSocket 之前?您确定您确实将名称存储到会话中吗?谷歌浏览器可以向您显示您的 Cookie。您可以在 github 上发布您的项目或最小示例吗? Did 'final String name = session("username"); return new WebSocketwebsocket 连接不是 Http。第一个握手请求看起来有点像 http,但确实包含其他字段。这就是为什么你不能在 websocket 请求中添加你的 http cookie。
来自***:
握手类似于 HTTP,因此服务器可以处理 HTTP 连接以及同一端口上的 WebSocket 连接。然而 涉及的具体领域,以及握手之后的事情,做 不符合 HTTP 协议。
如果您不想要用户名,您可以在 url 中使用令牌/会话 id,或者,如果在启动 websocket 连接之前无法实现登录/密码检索,请实现您自己的登录方法/password 通过 websocket 通信检索(例如服务器以特定格式请求登录/密码,客户端 js 做出反应,收集并发送回服务器)。
【讨论】:
【参考方案3】:在初始化为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 保护的
【讨论】:
以上是关于Playframework 2,Websockets 和 Session的主要内容,如果未能解决你的问题,请参考以下文章
Playframework 2,Websockets 和 Session
Play Framework 2.3 和 javascript websocket 客户端库