前言
chatgpt 可能大家都知道了,但是不是收费么,还有就是 需要科学上网;Bito 没有这些烦恼;阿里 通义灵码 也没有;
1:安装
vscode 搜索 Bito 安装, TONGYI Lingma 安装
2:注册登录
Bito 邮箱注册,登录需要去邮箱 复制个 验证码
阿里TONGYI Lingma 需要阿里云账号登录;
3:使用
Bito
全部代码如下
// Tokio Actor模型的WebSocket TLS服务器
use tokio::net::{TcpListener, TcpStream};
use tokio_tungstenite::accept_async;
use tokio_tungstenite::tungstenite::protocol::Message;
use tokio::sync::mpsc;
use tokio::time::{sleep, Duration};
// 定义Client Actor
struct ClientActor {
// 接受网络消息future
recv_network_future: mpsc::UnboundedReceiver<Message>,
// 逻辑消息处理future
logic_future: mpsc::UnboundedReceiver<Message>,
// 发送网络消息future
send_network_future: mpsc::UnboundedSender<Message>,
}
// 定义World Actor
struct WorldActor {
// 处理client actor需要转发给其他client actor的消息
forward_future: mpsc::UnboundedReceiver<Message>,
}
// 定义服务器
struct Server {
// 监听端口
port: u16,
// 全局唯一world actor
world_actor: WorldActor,
}
impl Server {
// 创建服务器
async fn new(port: u16) -> Self {
let (forward_future, _) = mpsc::unbounded_channel();
let world_actor = WorldActor { forward_future };
Self { port, world_actor }
}
// 启动服务器
async fn start(self) {
// 监听端口
let listener = TcpListener::bind(format!("0.0.0.0:{}", self.port)).await.unwrap();
// 循环接受连接
loop {
// 接受连接
let (stream, _) = listener.accept().await.unwrap();
// 将连接转换为WebSocket流
let ws_stream = accept_async(stream).await.unwrap();
// 创建Client Actor
let (recv_network_future, logic_future, send_network_future) = create_client_actor(ws_stream, self.world_actor.forward_future.clone());
// 启动Client Actor
tokio::spawn(async move {
client_actor(recv_network_future, logic_future, send_network_future).await;
});
}
}
}
// 创建Client Actor
fn create_client_actor(ws_stream: tokio_tungstenite::WebSocketStream<TcpStream>, forward_future: mpsc::UnboundedReceiver<Message>) -> (mpsc::UnboundedReceiver<Message>, mpsc::UnboundedReceiver<Message>, mpsc::UnboundedSender<Message>) {
// 接受网络消息future
let (recv_network_future, recv_network_sender) = mpsc::unbounded_channel();
// 逻辑消息处理future
let (logic_future, logic_sender) = mpsc::unbounded_channel();
// 发送网络消息future
let (send_network_future, send_network_receiver) = mpsc::unbounded_channel();
// 启动网络消息future
tokio::spawn(async move {
network_future(ws_stream, recv_network_sender, send_network_receiver).await;
});
// 启动逻辑消息处理future
tokio::spawn(async move {
logic_future(logic_sender, forward_future, send_network_future).await;
});
(recv_network_future, logic_future, send_network_future)
}
// Client Actor
async fn client_actor(recv_network_future: mpsc::UnboundedReceiver<Message>, logic_future: mpsc::UnboundedReceiver<Message>, send_network_future: mpsc::UnboundedSender<Message>) {
// 定时检查心跳消息
let mut heartbeat_interval = sleep(Duration::from_secs(5));
// 循环处理消息
loop {
tokio::select! {
// 接收网络消息
Some(msg) = recv_network_future => {
// 判断消息合法行
if is_valid_message(&msg) {
// 合法的发送给逻辑future
logic_future.send(msg).unwrap();
}
}
// 接收逻辑消息
Some(msg) = logic_future => {
// 解析消息
let msg_type = get_message_type(&msg);
// 安装消息号转发给world actor或发送网络future
match msg_type {
MessageType::ToWorld => {
world_actor.forward_future
代码都没显示完,这点有点恼火啊,理解词上,只能写个函数,娱乐下,复杂的搞不来;
再来个阿里的通义 灵码
全部代码如下
use tokio::net::{TcpListener};
use tokio_tungstenite::{accept_async, tungstenite::Message};
use futures::{future::BoxFuture, FutureExt, StreamExt};
use std::sync::Arc;
use mpsc::unbounded;
// 创建一个全局唯一的World Actor
struct WorldActor {
txs: Vec<UnboundedSender<Message>>,
}
impl WorldActor {
async fn broadcast(&self, msg: Message) {
for tx in &self.txs {
let _ = tx.send(msg.clone());
}
}
}
#[tokio::main]
async fn main() {
// 初始化World Actor
let world_actor = Arc::new(WorldActor {
txs: Vec::new(),
});
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
loop {
let (socket, _) = listener.accept().await.unwrap();
tokio::spawn(async move {
let (ws_stream, _) = accept_async(socket).await.expect("Failed to accept connection");
let (tx_to_world, rx_from_client) = unbounded();
let (tx_to_client, mut rx_from_world) = unbounded();
// 将client的发送通道添加到World Actor中
world_actor.txs.push(tx_to_client);
let heartbeat_task = tokio::spawn(heartbeat(rx_from_world));
let network_recv_future = ws_stream.for_each(|msg| {
// 网络消息future:接受网络消息并验证合法性
if is_valid_message(msg) {
// 合法则发送给逻辑future
tx_to_world.unbounded_send(msg).unwrap();
}
future::ready(())
});
let logic_handle_future = tokio::spawn(logic_handler(rx_from_client, tx_to_world));
let network_send_future = tokio::spawn(network_sender(ws_stream, rx_from_world));
future::join3(network_recv_future, logic_handle_future, network_send_future)
.await;
// 在连接断开时从World Actor移除client的发送通道
world_actor.txs.retain(|tx| tx != &tx_to_client);
});
}
}
async fn heartbeat(rx_from_world: UnboundedReceiver<Message>) {
// 心跳检测任务...
}
async fn logic_handler(mut rx_from_client: UnboundedReceiver<Message>, tx_to_world: UnboundedSender<Message>) {
while let Some(msg) = rx_from_client.recv().await {
// 逻辑future:解析消息并根据消息号转发给world actor或其他client actor
match parse_and_dispatch_message(msg) {
// 转发给world actor
Some(world_msg) => tx_to_world.unbounded_send(world_msg).unwrap(),
// 自行处理
None => handle_local_message(msg),
}
}
}
async fn network_sender(mut ws_stream: WebSocketStream<TcpStream>, mut rx_from_world: UnboundedReceiver<Message>) {
while let Some(msg) = rx_from_world.recv().await {
// 发送网络future:接收消息并发送至前端
if is_valid_for_network(msg) {
if let Err(e) = ws_stream.send(msg).await {
println!("Error sending message: {}", e);
}
}
}
}
个人觉得 TONGYI Lingma 还比不上Bito ;
4:后续有时间继续测试其他AI CODE
如果觉得有用,麻烦点个赞,加个收藏