Socket.IO是一个完全由JavaScript实现、基于Node.js、支持WebSocket的协议用于实时通信、跨平台的开源框架,它包括了客户端的JavaScript和服务器端的Node.js。
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
市面上关于flutter即时通信的文章并不是很全,经过一系列的踩坑之后,总结出了这篇相对较为完整简单的文章。
如没有看过 Nest
官网的 WebSocket
用法,请先查看官网的使用方式。
一、Nest.js中部署Socket.io
1.下载依赖的包
npm install @nestjs/websockets @nestjs/platform-socket.io --save
npm install @types/socket.io --save-dev
2.创建gatway文件
Gateway 是用 @WebSocketGateway() 装饰的类。
Gateway 的内部使用了 socket.io,不过你也可以使用其它的库,比如原生的 Web sockets。Gateway 就像是一个简单的 provider,你可以通过构造方法给它注入依赖,你也可以在其它的类里面注入使用 gateway 。
确保 gateway 运行,需要把它放在一个 providers 数组里
nest g gateway futter/flutter
3.flutter.gateway.ts文件中的主要代码段
import {
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
} from '@nestjs/websockets'
import { Server, Socket } from 'socket.io'
@WebSocketGateway({
// 域名
namespace: '/flutter',
// 解决跨域
allowEIO3: true,
cors: {
origin: /.*/,
credentials: true,
},
})
export class FlutterGateway {
@WebSocketServer() server: Server
handleConnection(client: Socket) {
this.server.on('connection', () => {
console.log('与服务器建立连接成功')
})
}
// 加入房间
@SubscribeMessage('joinRoom')
handleJoinRoom(client: Socket, payload) {
console.log(payload)
client.join(payload.roomId)
client.emit('joinRoom', payload.roomId)
}
// 离开房间
@SubscribeMessage('leaveRoom')
handleLeaveRoom(client: Socket, payload) {
client.leave(payload.roomId)
client.emit('leaveRoom', payload.roomId)
}
// 接受网页发送的数据
@SubscribeMessage('message')
handleMessage(client: any, payload: any) {
console.log(payload.message)
// 发送网页的数据给flutter端
// client.emit('toflutter', payload.message)
this.server.emit('toflutter', payload.message)
}
}
二、在flutter中的配置
1.在flutter目录的yam文件中引入包
socket_io_client: ^1.0.1
2.导入包socket.io的包
import 'package:socket_io_client/socket_io_client.dart' as IO;
3.基本代码段都有注释,不废话了直接上代码
import 'package:flutter/material.dart';
// 导入socket库
import 'package:socket_io_client/socket_io_client.dart' as IO;
class SocketPage extends StatefulWidget {
SocketPage({Key? key}) : super(key: key);
@override
_SocketPageState createState() => _SocketPageState();
}
class _SocketPageState extends State<SocketPage> {
TextEditingController controller = TextEditingController();
// 实例化socket
late IO.Socket socket;
// 数据
List messageList = [];
@override
void initState() {
super.initState();
// 路径
socket = IO.io('http://172.20.10.5:3000/flutter', <String, dynamic>{
'transports': ['websocket']
});
// 连接成功
socket.on('connect', (_) {
print('connect..');
});
socket.on("toflutter", (data) {
print(data);
// 将得到的数据存放到数组
setState(() {
messageList.add(data);
print(messageList);
});
});
// print(messageList);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('socket测试'),
),
body: Column(
children: [
Container(
child: TextField(
controller: controller,
),
),
ElevatedButton(
onPressed: () {
// 发送数据给服务端
socket.emit("message", {"message": controller.text});
},
child: Text("发送信息")),
Container(
height: 400,
child: ListView.builder(
itemBuilder: (context, index) {
return messageList.length == 0
? Text("没有聊天记录")
: ListTile(
title: Text("${messageList[index]}"),
);
},
itemCount: messageList.length,
),
)
],
));
}
}
三、完成效果
界面方面还没有详细设计,可能比较丑,等慢慢美化界面后上传github吧。