You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

작성중 컨텐츠...




CounselorRoomActor에 상담원 옵저버도 초청해 조인시키고 싶습니다.
옵저버 상담원은 N개로 대화내용을 모두 수신받을수 있습니다.
하지만 고객에게 메시지 전송은 할당된 counselor만 가능합니다.

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] 중에 ..
즉 요청은 고유한 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)
    }


 


 


 


 



  • No labels