웹소켓을 액터와 연결하여 조금더 실시간 웹소켓 기능을 풍부하게 사용할수 있는 방법입니다.
사용되는 웹프레임워크및 웹소켓모듈에따라 웹소켓핸들러를 연결하는방법은 다양할것이지만
웹소켓을 AKKA의 Actor로 연결한것만으로, AKKA에서 제공되는 여러가지 분산처리 기능들을
웹소켓과 연동되어 활용이 가능해집니다.
언어에 종속적이지 않는 설계에관련된 컨셉입니다.
설계
- EventBus : Pub/Sub방식으로 메시지를 전달하는 방식입니다.
- WebSockHandler : 웹소케메시지를 처리하는 모듈입니다.
- WebSockActor : 웹소켓 핸들러와 EventBus를 연결해줍니다.
소켓 컨트롤러를 액터와 연동하기
@Singleton class SockController @Inject() (implicit system: ActorSystem, materializer: Materializer) extends play.api.mvc.Controller{ def socket = WebSocket.accept[String, String] { request => ActorFlow.actorRef(out => MyWebSocketActor.props(out,system)) } def testsock = Action { Ok(views.html.testsock ("Your WebSock is ready.")) } }
웹소켓을 다루는 방식은 웹프레임워크마다 다르며 , PlayFrameWork에서는 웹소켓 핸들러를
위와같은 코드를 통해 액터로 연동이 가능합니다.
메시지를 처리하는 웹소켓 액터구현
object MyWebSocketActor { def props(out: ActorRef, system:ActorSystem ) = Props(new MyWebSocketActor(out,system)) } class MyWebSocketActor(out: ActorRef, system:ActorSystem) extends Actor { def receive = { case msg: String => val json:JsValue = Json.parse(msg) val pid = (json \ "pid").asOpt[String] pid match { case Some("WordParserInfo") => val text:String = (json \ "text").as[String] val reqID:Int = (json \ "reqID").as[Int] system.actorSelection("/user/wordParserActor") ! AskParser(text,1,reqID) case None => out ! ("None") } case msg: JsValue => out ! msg.toString() case msg: SentenceMainListModel => out ! "ttt" } override def postStop() = { //someResource.close() } }
웹소켓을 액터로 연결하였기때문에 Akka가가진 EventBus및 AkkaStream등과의
연동을 통한 구조설계가 가능해졌습니다.
이벤트버스
//사용자를 만든다. -사용자 접속시 TopicEventBus.CreateActor("sangman"); TopicEventBus.CreateActor("rapael"); TopicEventBus.CreateActor("pierre"); //뉴스 메시지를 만든다. MsgEnvelope msg1 = new MsgEnvelope("News", "all", "Hello"); MsgEnvelope msg2 = new MsgEnvelope("News", "all", "Hola"); MsgEnvelope msg3 = new MsgEnvelope("News", "all", "안녕하세요"); //각각의 사용자는 보고싶은 언어로 뉴스섹션을 선택한다. 추가 구독도 가능하다. TopicEventBus.Subscribe("sangman", "News", "스포츠", "kr"); TopicEventBus.Subscribe("rapael", "News", "스포츠", "es"); TopicEventBus.Subscribe("pierre", "News", "스포츠", "fr"); //서버에 의해 Push 메시지가 발생한다. TopicEventBus.Publish(msg1, "스포츠", "en"); TopicEventBus.Publish(msg2, "스포츠", "es"); TopicEventBus.Publish(msg3, "스포츠", "kr"); //각각의 사용자에게 , 언어에 맞는 뉴스가 전달되며, //대부분의 실시간 통신에서 Pub/Sub메시지패턴은 유용한 방법입니다.
이벤트 버스를 액터설계에 반영하여, 조금더 풍성한 웹소켓기능을 구현할수가 있습니다.
추가참고:
이점
웹소켓에 EventBus기능을 부여하는것은 다양하고 복잡한 메시징 처리에대한
구현을 일괄적이고 단순하게 만들어줍니다.