작성중 컨텐츠... |
CounselorRoomActor에 상담원 옵저버도 초청해 조인시키고 싶습니다. |
To invite observer counselors to the `CounselorRoomActor` and allow them to receive all conversation messages, but restrict sending messages to the client to only the assigned counselor, you can modify the `CounselorRoomActor` class as follows: 1. Add a list to store observer counselors. 2. Update the `AssignCounselor` command to handle observer counselors. 3. Modify the message handling methods to send messages to observer counselors. Here is the updated code: ```kotlin sealed class CounselorRoomCommand data class InvitePersonalRoomActor(val personalRoomActor: ActorRef<PersonalRoomCommand>, val replyTo: ActorRef<CounselorRoomResponse>) : CounselorRoomCommand() data class ChangeStatus(val status: CounselorRoomStatus, val replyTo: ActorRef<CounselorRoomResponse>) : CounselorRoomCommand() data class AssignCounselor(val counselorActor: ActorRef<CounselorCommand>, val observers: List<ActorRef<CounselorCommand>> = emptyList()) : CounselorRoomCommand() data class SendMessageToPersonalRoom(val message: String) : CounselorRoomCommand() data class SendToCounselor(val message: String) : CounselorRoomCommand() ``` ```kotlin class CounselorRoomActor private constructor( context: ActorContext<CounselorRoomCommand>, private val name: String ) : AbstractBehavior<CounselorRoomCommand>(context) { private var status: CounselorRoomStatus = CounselorRoomStatus.WAITING private lateinit var personalRoom: ActorRef<PersonalRoomCommand> private lateinit var counselor: ActorRef<CounselorCommand> private val observerCounselors = mutableListOf<ActorRef<CounselorCommand>>() companion object { fun create(name: String): Behavior<CounselorRoomCommand> { return Behaviors.setup { context -> CounselorRoomActor(context, name) } } } override fun createReceive(): Receive<CounselorRoomCommand> { return newReceiveBuilder() .onMessage(InvitePersonalRoomActor::class.java, this::onInvitePersonalRoomActor) .onMessage(ChangeStatus::class.java, this::onChangeStatus) .onMessage(AssignCounselor::class.java, this::onAssignCounselor) .onMessage(SendMessageToPersonalRoom::class.java, this::onSendMessageToPersonalRoom) .onMessage(SendToCounselor::class.java, this::onSendToCounselor) .build() } private fun onSendToCounselor(sendToCounselor: SendToCounselor): Behavior<CounselorRoomCommand>? { if(::counselor.isInitialized){ counselor.tell(SendToCounselorHandlerTextMessage(sendToCounselor.message)) observerCounselors.forEach { it.tell(SendToCounselorHandlerTextMessage(sendToCounselor.message)) } } else { context.log.error("CounselorActor is not initialized") } return this } private fun onSendMessageToPersonalRoom(sendMessageToPersonalRoom: SendMessageToPersonalRoom): Behavior<CounselorRoomCommand> { if(::personalRoom.isInitialized){ personalRoom.tell(SendTextMessage(sendMessageToPersonalRoom.message)) } else { context.log.error("PersonalRoomActor is not initialized") } return this } private fun onAssignCounselor(command: AssignCounselor): Behavior<CounselorRoomCommand> { counselor = command.counselorActor observerCounselors.clear() observerCounselors.addAll(command.observers) counselor.tell(SendToCounselorSystemMessage("You are assigned to the room: $name")) observerCounselors.forEach { it.tell(SendToCounselorSystemMessage("You are observing the room: $name")) } return this } private fun onInvitePersonalRoomActor(command: InvitePersonalRoomActor): Behavior<CounselorRoomCommand> { context.log.info("Invited PersonalRoomActor: ${command.personalRoomActor}") personalRoom = command.personalRoomActor command.replyTo.tell(InvitationCompleted) return this } private fun onChangeStatus(command: ChangeStatus): Behavior<CounselorRoomCommand> { status = command.status context.log.info("CounselorRoom status changed to: $status") command.replyTo.tell(StatusChangeCompleted(status)) return this } } ``` In this updated code, the `AssignCounselor` command now accepts a list of observer counselors. The `onAssignCounselor` method assigns the main counselor and adds the observers to the `observerCounselors` list. The `onSendToCounselor` method sends messages to both the main counselor and the observers. |
onAssignCounselor 와 Observer 초대는 구분하고 싶습니다. |
To separate the assignment of a counselor and the invitation of observers, you can create a new command for inviting observers. Here is the updated code: 1. Add a new command `InviteObservers` to handle the invitation of observer counselors. 2. Implement the `onInviteObservers` method to process this new command. ```kotlin sealed class CounselorRoomCommand data class InvitePersonalRoomActor(val personalRoomActor: ActorRef<PersonalRoomCommand>, val replyTo: ActorRef<CounselorRoomResponse>) : CounselorRoomCommand() data class ChangeStatus(val status: CounselorRoomStatus, val replyTo: ActorRef<CounselorRoomResponse>) : CounselorRoomCommand() data class AssignCounselor(val counselorActor: ActorRef<CounselorCommand>) : CounselorRoomCommand() data class InviteObservers(val observers: List<ActorRef<CounselorCommand>>) : CounselorRoomCommand() data class SendMessageToPersonalRoom(val message: String) : CounselorRoomCommand() data class SendToCounselor(val message: String) : CounselorRoomCommand() ``` ```kotlin class CounselorRoomActor private constructor( context: ActorContext<CounselorRoomCommand>, private val name: String ) : AbstractBehavior<CounselorRoomCommand>(context) { private var status: CounselorRoomStatus = CounselorRoomStatus.WAITING private lateinit var personalRoom: ActorRef<PersonalRoomCommand> private lateinit var counselor: ActorRef<CounselorCommand> private val observerCounselors = mutableListOf<ActorRef<CounselorCommand>>() companion object { fun create(name: String): Behavior<CounselorRoomCommand> { return Behaviors.setup { context -> CounselorRoomActor(context, name) } } } override fun createReceive(): Receive<CounselorRoomCommand> { return newReceiveBuilder() .onMessage(InvitePersonalRoomActor::class.java, this::onInvitePersonalRoomActor) .onMessage(ChangeStatus::class.java, this::onChangeStatus) .onMessage(AssignCounselor::class.java, this::onAssignCounselor) .onMessage(InviteObservers::class.java, this::onInviteObservers) .onMessage(SendMessageToPersonalRoom::class.java, this::onSendMessageToPersonalRoom) .onMessage(SendToCounselor::class.java, this::onSendToCounselor) .build() } private fun onSendToCounselor(sendToCounselor: SendToCounselor): Behavior<CounselorRoomCommand>? { if(::counselor.isInitialized){ counselor.tell(SendToCounselorHandlerTextMessage(sendToCounselor.message)) observerCounselors.forEach { it.tell(SendToCounselorHandlerTextMessage(sendToCounselor.message)) } } else { context.log.error("CounselorActor is not initialized") } return this } private fun onSendMessageToPersonalRoom(sendMessageToPersonalRoom: SendMessageToPersonalRoom): Behavior<CounselorRoomCommand> { if(::personalRoom.isInitialized){ personalRoom.tell(SendTextMessage(sendMessageToPersonalRoom.message)) } else { context.log.error("PersonalRoomActor is not initialized") } return this } private fun onAssignCounselor(command: AssignCounselor): Behavior<CounselorRoomCommand> { counselor = command.counselorActor counselor.tell(SendToCounselorSystemMessage("You are assigned to the room: $name")) return this } private fun onInviteObservers(command: InviteObservers): Behavior<CounselorRoomCommand> { observerCounselors.clear() observerCounselors.addAll(command.observers) observerCounselors.forEach { it.tell(SendToCounselorSystemMessage("You are observing the room: $name")) } return this } private fun onInvitePersonalRoomActor(command: InvitePersonalRoomActor): Behavior<CounselorRoomCommand> { context.log.info("Invited PersonalRoomActor: ${command.personalRoomActor}") personalRoom = command.personalRoomActor command.replyTo.tell(InvitationCompleted) return this } private fun onChangeStatus(command: ChangeStatus): Behavior<CounselorRoomCommand> { status = command.status context.log.info("CounselorRoom status changed to: $status") command.replyTo.tell(StatusChangeCompleted(status)) return this } } ``` In this updated code, the `InviteObservers` command is used to invite observer counselors separately from assigning the main counselor. The `onInviteObservers` method handles this new command. |
InviteObservers 에서 한명씩 초청하고 싶습니다. |
To invite observers one by one, you can modify the `InviteObservers` command to accept a single observer and update the `onInviteObservers` method accordingly. Here is the updated code: ```kotlin data class InviteObserver(val observer: ActorRef<CounselorCommand>) : CounselorRoomCommand() ``` ```kotlin private fun onInviteObserver(command: InviteObserver): Behavior<CounselorRoomCommand> { observerCounselors.add(command.observer) command.observer.tell(SendToCounselorSystemMessage("You are observing the room: $name")) return this } ``` Update the `createReceive` method to handle the new `InviteObserver` command: ```kotlin override fun createReceive(): Receive<CounselorRoomCommand> { return newReceiveBuilder() .onMessage(InvitePersonalRoomActor::class.java, this::onInvitePersonalRoomActor) .onMessage(ChangeStatus::class.java, this::onChangeStatus) .onMessage(AssignCounselor::class.java, this::onAssignCounselor) .onMessage(InviteObserver::class.java, this::onInviteObserver) .onMessage(SendMessageToPersonalRoom::class.java, this::onSendMessageToPersonalRoom) .onMessage(SendToCounselor::class.java, this::onSendToCounselor) .build() } ``` This allows you to invite observers one by one using the `InviteObserver` command. |
CounselorManagerActor에 옵저버 상담원을 추가하는 이벤트및 작동구현 해 |
To add an event and implementation for adding observer counselors in `CounselorManagerActor`, follow these steps: 1. Define a new command `AddObserverCounselor`. 2. Implement the handler method `onAddObserverCounselor` in `CounselorManagerActor`. 3. Update the `createReceive` method to handle the new command. Here is the updated code: ### Define the new command ```kotlin sealed class CounselorManagerCommand data class AddObserverCounselor(val roomName: String, val observer: ActorRef<CounselorCommand>, val replyTo: ActorRef<CounselorManagerResponse>) : CounselorManagerCommand() ``` ### Implement the handler method ```kotlin private fun onAddObserverCounselor(command: AddObserverCounselor): Behavior<CounselorManagerCommand> { val counselorRoomActor = counselorRooms[command.roomName] return if (counselorRoomActor != null) { counselorRoomActor.tell(InviteObserver(command.observer)) command.replyTo.tell(CounselorManagerSystemResponse("Observer counselor added to room: ${command.roomName}")) this } else { command.replyTo.tell(ErrorResponse("Room ${command.roomName} not found.")) this } } ``` ### Update the `createReceive` method ```kotlin override fun createReceive(): Receive<CounselorManagerCommand> { return newReceiveBuilder() .onMessage(CreateCounselor::class.java, this::onCreateCounselor) .onMessage(CreateRoom::class.java, this::onCreateRoom) .onMessage(RequestCounseling::class.java, this::onRequestCounseling) .onMessage(GetCounselor::class.java, this::onGetCounselor) .onMessage(GetCounselorRoom::class.java, this::onGetCounselorRoom) .onMessage(UpdateRoutingRule::class.java, this::onUpdateRoutingRule) .onMessage(EvaluateRoutingRule::class.java, this::onEvaluateRoutingRule) .onMessage(AddObserverCounselor::class.java, this::onAddObserverCounselor) .build() } ``` This implementation allows you to add observer counselors to a specific room by sending the `AddObserverCounselor` command to the `CounselorManagerActor`. |
Observer는 counselors[command.name] 중에 .. |
To ensure that observers are added based on a unique name, you can modify the `onAddObserverCounselor` method to look up the observer by name from the `counselors` map. Here is the updated code: 1. Update the `AddObserverCounselor` command to include the observer's name. 2. Modify the `onAddObserverCounselor` method to look up the observer by name. ### Update the `AddObserverCounselor` command ```kotlin data class AddObserverCounselor(val roomName: String, val observerName: String, val replyTo: ActorRef<CounselorManagerResponse>) : CounselorManagerCommand() ``` ### Modify the `onAddObserverCounselor` method ```kotlin private fun onAddObserverCounselor(command: AddObserverCounselor): Behavior<CounselorManagerCommand> { val counselorRoomActor = counselorRooms[command.roomName] val observer = counselors[command.observerName] return if (counselorRoomActor != null && observer != null) { counselorRoomActor.tell(InviteObserver(observer)) command.replyTo.tell(CounselorManagerSystemResponse("Observer counselor ${command.observerName} added to room: ${command.roomName}")) this } else { val errorMessage = when { counselorRoomActor == null -> "Room ${command.roomName} not found." observer == null -> "Observer counselor ${command.observerName} not found." else -> "Unknown error." } command.replyTo.tell(ErrorResponse(errorMessage)) this } } ``` This implementation ensures that the observer is added based on a unique name. |
지금까지 완성한 기능을 CounselorManagerActorTest 에 유닛테스트를 추가 |
@Test fun testAddObserverCounselor() { val probe = testKit.createTestProbe<CounselorManagerResponse>() val counselorManager = testKit.spawn(CounselorManagerActor.create()) // Create a counselor and a room counselorManager.tell(CreateCounselor("observer1", probe.ref)) probe.receiveMessage() counselorManager.tell(CreateRoom("room1", probe.ref)) probe.receiveMessage() // Add observer counselor to the room counselorManager.tell(AddObserverCounselor("room1", "observer1", probe.ref)) val response = probe.receiveMessage() assertEquals(CounselorManagerSystemResponse("Observer counselor observer1 added to room: room1"), response) } |
연구 저장소 : https://github.com/psmon/kopring-reactive-labs