如何仅写入一个具有现有WebSocket连接而不是所有用户的用户?

发布于 2025-02-03 16:34:18 字数 3644 浏览 4 评论 0原文

这就是我所拥有的: 在这里,传入消息将发送给所有用户。

fun Route.chatSocket(roomController: RoomController) {
    webSocket("/chat-socket" ) {
        val session = call.sessions.get<ChatSession>()
        if (session==null) {
            close(CloseReason(CloseReason.Codes.VIOLATED_POLICY,"No session"))
            return@webSocket
        }
        try {
            roomController.onJoin(
            username = session.username,
            sessionId = session.sessionId,
            socket = this
        )
       incoming.consumeEach { frame ->
            if (frame is Frame.Text) {
                roomController.sendMessage(
                    senderUsername = session.username,
                    message = frame.readText()
                )
            }

        }

        } catch (e: MemberAlredyExistExpetion) {
            call.respond(HttpStatusCode.Conflict)
        } finally {
            roomController.tryDisconnect(session.username)
        }
    }
}

这是RoomController:

class RoomController(
    private val messageDataSource: MessageDataSource
) {
    private val members = ConcurrentHashMap<String,Member>()

    fun onJoin(
        username:String,
        sessionId:String,
        socket: WebSocketSession
    ) {
        if (members.containsKey(username)) {
            throw MemberAlredyExistExpetion()
        }
        members[username] = Member(
            username = username,
            sessionId = sessionId,
            socket  = socket
        )
    }

   suspend fun sendMessage(senderUsername: String, message: String) {
        members.values.forEach { member ->
            val messageEntity = Message(
                text = message,
                username = senderUsername,
                timestamp = System.currentTimeMillis()
            )
            messageDataSource.insertMessage(messageEntity)

            val parsedMessage = Json.encodeToString(messageEntity)
            member.socket.send(Frame.Text(parsedMessage))
        }
    }

在这里,我尝试实现一个可以直接写给用户的命令。但是它不起作用。

fun Route.chatToOne(roomController: RoomController) {
    webSocket("/whisper") {
        val session = call.sessions.get<ChatSessionToOne>()
        if (session==null) {
            close(CloseReason(CloseReason.Codes.VIOLATED_POLICY,"No Session"))
            return@webSocket
        }
        try {
            incoming.consumeEach { frame ->
                if (frame is Frame.Text) {
                    roomController.sendMessageToOneUser(
                        senderUsername = session.username,
                        targetUsername = session.targetusername,
                        message = frame.readText()
                    )
                }
            }
        } catch (e: MemberAlredyExistExpetion) {
            call.respond(HttpStatusCode.Conflict)
        }
    }
}

在这里,来自RoomController的代码:

suspend fun sendMessageToOneUser(senderUsername: String, targetUsername :String, message: String) {
        members.values.forEach { member ->
            if (member.username == targetUsername) {
                val messageEntity = Message(
                    text = message,
                    username = targetUsername,
                    timestamp = System.currentTimeMillis()
                )
                messageDataSource.insertMessage(messageEntity)

                val parsedMessage = Json.encodeToString(messageEntity)
                member.socket.send(Frame.Text(parsedMessage))
            }
        }
    }

如何仅写入一个具有现有WebSocket连接而不是所有用户的用户?

Here's what I have:
Here, incoming messages are sent to all users.

fun Route.chatSocket(roomController: RoomController) {
    webSocket("/chat-socket" ) {
        val session = call.sessions.get<ChatSession>()
        if (session==null) {
            close(CloseReason(CloseReason.Codes.VIOLATED_POLICY,"No session"))
            return@webSocket
        }
        try {
            roomController.onJoin(
            username = session.username,
            sessionId = session.sessionId,
            socket = this
        )
       incoming.consumeEach { frame ->
            if (frame is Frame.Text) {
                roomController.sendMessage(
                    senderUsername = session.username,
                    message = frame.readText()
                )
            }

        }

        } catch (e: MemberAlredyExistExpetion) {
            call.respond(HttpStatusCode.Conflict)
        } finally {
            roomController.tryDisconnect(session.username)
        }
    }
}

And here is the roomController:

class RoomController(
    private val messageDataSource: MessageDataSource
) {
    private val members = ConcurrentHashMap<String,Member>()

    fun onJoin(
        username:String,
        sessionId:String,
        socket: WebSocketSession
    ) {
        if (members.containsKey(username)) {
            throw MemberAlredyExistExpetion()
        }
        members[username] = Member(
            username = username,
            sessionId = sessionId,
            socket  = socket
        )
    }

   suspend fun sendMessage(senderUsername: String, message: String) {
        members.values.forEach { member ->
            val messageEntity = Message(
                text = message,
                username = senderUsername,
                timestamp = System.currentTimeMillis()
            )
            messageDataSource.insertMessage(messageEntity)

            val parsedMessage = Json.encodeToString(messageEntity)
            member.socket.send(Frame.Text(parsedMessage))
        }
    }

Here I have tried to implement a command with which I can write directly to a user. But it don`t work.

fun Route.chatToOne(roomController: RoomController) {
    webSocket("/whisper") {
        val session = call.sessions.get<ChatSessionToOne>()
        if (session==null) {
            close(CloseReason(CloseReason.Codes.VIOLATED_POLICY,"No Session"))
            return@webSocket
        }
        try {
            incoming.consumeEach { frame ->
                if (frame is Frame.Text) {
                    roomController.sendMessageToOneUser(
                        senderUsername = session.username,
                        targetUsername = session.targetusername,
                        message = frame.readText()
                    )
                }
            }
        } catch (e: MemberAlredyExistExpetion) {
            call.respond(HttpStatusCode.Conflict)
        }
    }
}

And here the code from the roomController:

suspend fun sendMessageToOneUser(senderUsername: String, targetUsername :String, message: String) {
        members.values.forEach { member ->
            if (member.username == targetUsername) {
                val messageEntity = Message(
                    text = message,
                    username = targetUsername,
                    timestamp = System.currentTimeMillis()
                )
                messageDataSource.insertMessage(messageEntity)

                val parsedMessage = Json.encodeToString(messageEntity)
                member.socket.send(Frame.Text(parsedMessage))
            }
        }
    }

How can I write to only one user with an existing WebSocket connection instead of to all users?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文