2016-01-12 61 views
1

我對Scala,Play框架和Akka都很陌生。在我目前正在開發的項目中,Web應用程序的用戶應該能夠以異步的方式向服務器請求幾件事情(如開始特定的計算)。如果服務器完成,它應該通知用戶也是異步的。我解決了其上建立的WebSocket連接這方面的需求,當用戶第一次使用應用程序連接和WebSocket的由UserActor,其連接到用戶會話處理:玩家框架用戶演員與用戶會話

def ws = WebSocket.tryAcceptWithActor[JsValue, JsValue] { implicit request => 

    Future.successful(request.session.get(UID) match { 
     case None => Left(Forbidden) 
     case Some(uid) => Logger.info("WebSocket has accepted the request with uid " + uid) 
          Right(UserActor.props(uid)) 
    }) 
} 

目前,唯一的事情UserActor確實接收來自WebSocket的消息,如JsValue

def index = Action { implicit request => { 
    val uid = request.session.get(UID).getOrElse { 
     counter += 1 
     counter.toString 
    } 
    Ok(views.html.index(uid)).withSession { 
     Logger.debug("create uid " + uid) 
     request.session + (UID -> uid) 
    }} 
} 

UserActor所述應該表示在服務器上的實際用戶,從而包括所有的動作的用戶可以在服務器上執行的邏輯:請求索引時生成會話的UID。只要我通過WebSocket發送所有用戶交互,此工作正常。

現在情況如何與其他用戶輸入,如表單提交?該應用程序包含一個表單,其數據不應超過WebSocket,而應提交POST請求(可能帶有AJAX)並將其綁定到控制器中,如文檔中所述。

def saveContact = Action { implicit request => 
    contactForm.bindFromRequest.fold(
    formWithErrors => { 
     BadRequest(views.html.contact.form(formWithErrors)) 
    }, 
    contact => { 
     val contactId = Contact.save(contact) 
     Redirect(routes.Application.showContact(contactId)).flashing("success" -> "Contact saved!") 
    } 
) 
} 

本示例摘自Playframework documentation

現在,我如何鏈接表單提交處理程序與UserActor?假設我想告訴用戶演員表格已經提交。一個簡單的例子是,UserActor只要收到一個表格,就會通過WebSocket向客戶端發送一個表單值。所以基本上這個問題歸結爲我想發送來自ControllerUserActor消息的問題。

我可能想出了通過WebSocket發送所有表單數據的想法,但我也希望在將來實現大數據的上傳,我想要像解釋in this blog post所述那樣處理。然後,我可以想象的一個場景是UserActor應該收到它接收的每個塊的消息。

我想一個問題是,UserActorWebSocketActor是相同的,我寧願要拆他們的邏輯,使得UserActor只與會議相關的,但我不知道如何做到這一點。也許我需要另一個演員,說一個UserManager,跟蹤目前UserActors,並允許訪問UserActors

您是否有任何建議,建議或示例應用程序也處理這種情況?非常感謝你提前。

問候

回答

0

不要使用您傳遞給tryAcceptWithActorUser的代表演員。它應該代表與該用戶的特定會話。可能地,用戶可能在特定時間打開的許多併發會話(多個瀏覽器或標籤)之一。

創建一個單獨的actor來表示用戶及其可以執行的所有操作。現在會話演員應該將他們的消息轉發給用戶演員。傳統的控制器方法也可以將請求轉發給相應的用戶參與者。