跟我一起学“仓颉”编程语言-聊天室

本案例来自《图解仓颉编程-高级篇》书5-15和5-16的代码。代码地址:仓颉编程快速上手-刘玥_张荣超

一、聊天室服务端

package Study
import std.socket.*
import std.collection.*

//存储所有在线客户端
let onlineClients = ArrayList()

/*
* 接收消息并将该消息转发给所有在线的客户端
*/
func receiveMessage(client: TcpSocket) {
    let socketAddress = client.remoteAddress.toString()
    let messageHead = socketAddress.toString() + "#"
    let onlineMessage = messageHead + "上线了!"
    sendMessage(onlineMessage.toArray())
    let buffer = Array(1024, item: 0)
    var len: Int64
    while (true) {
        len = client.read(buffer)
        if (len == 0) {
            // 从onlineClients中移除client
            onlineClients.removeIf {socket: TcpSocket => socket == client}
            client.close()  // 关闭client
            let offlineMessage = messageHead + "下线了!"
            sendMessage(offlineMessage.toArray())
            break
        }
        let messageToSend = messageHead + String.fromUtf8(buffer[0..len])
        sendMessage(messageToSend.toArray())
    }
}

/*
* 发送消息
*/
func sendMessage(buffer: Array) {
    for (clinetSocket in onlineClients) {
        clinetSocket.write(buffer)
    }
}

/*
* 服务端启动
*/
func start() {
    try (
        server = TcpServerSocket(bindAt: 9999)
    ) {
        server.bind()
        println("服务端已启动!")
        while (true) {  // 与多个客户端连接
            let client = server.accept()
            onlineClients.append(client)
            spawn {
                receiveMessage(client)
            }
        }
    }
}

main() {
    start()
}

二、聊天室客户端

package Sender
import std.socket.*
import std.console.*
import std.convert.*

/*
* 发送消息
*/
func sendMessage(client: TcpSocket) {
    while (true) {
        let optMessage = Console.stdIn.readln()
        if (let Some(message) <- optMessage) {
            if (message == "N" || message == "n") {
                client.close()
                break
            }
            client.write(message.toArray())
        } else {
            println("非法无效!")
        }
    }
}

/*
* 接收消息
*/
func receiveMessage(client: TcpSocket) {
    let buffer = Array(1024, item: 0)
    while (true) {
        try {
            let len = client.read(buffer)
            let message = String.fromUtf8(buffer[0..len])
            let array = message.split("#", 2)
            let socketAddress = array[0]
            let messageBody = array[1]
            if (socketAddress == client.localAddress.toString()) {
                // 输出我自己的消息
                println("我: ${messageBody}")
            } else {
                // 输出其他人的消息
                println("${socketAddress}: ${messageBody}")
            }
        } catch (e: SocketException) {
            println("我已下线")
            break
        }
    }
}

/*
* 客户端启动
*/
func start() {
    let client = TcpSocket("127.0.0.1", 9999)
    client.connect()
    println("客户端${client.localAddress}已启动!")
    // 发送线程
    let sendFuture = spawn {
        sendMessage(client)
    }

    // 接收线程
    let receiveFuture = spawn {
        receiveMessage(client)
    }
    sendFuture.get() 
    receiveFuture.get()
}

main() {
    start()
}

三、小结

本章为大家详细的介绍了仓颉编程语言中聊天室的内容,下一章,为大家带来反射和注解的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉服务端开发有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家!!!

你可能感兴趣的:(跟我一起学“仓颉”编程语言,仓颉编程语言,仓颉服务端开发,华为)