실시간 채팅 앱 - Flutter, Node.js 및 Socket.io
전제 조건
다음이 PC에 설치되어 실행 중이어야 합니다.
Nodejs(서버 측)
real_chat_node라는 폴더를 만들고 터미널에서 엽니다. 그런 다음 다음 명령을 실행합니다.
npm init
Enter를 눌러 기본값을 승인하십시오. 다음으로 노드를 설치할 때 기본적으로 제공되는 npm을 통해 필요한 패키지를 설치합니다.
npm install express nodemon http socket.io
즐겨찾는 IDE로 폴더를 엽니다. 그런 다음 package.json으로 이동하고 스크립트에서 개발 키를 추가합니다.
다음으로 루트 디렉터리에 index.js 파일을 만듭니다. 그 안에 다음 코드를 작성합니다.
const app = require('express')()
const http = require('http').createServer(app)
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!")
})
http.listen(8080)
터미널에서 다음 명령을 입력합니다.npm run dev
실행 상태로 두고 http://localhost:8080으로 이동하면 메시지가 표시됩니다.
이제 nodejs 앱에 소켓을 추가하겠습니다.
const app = require('express')()
const http = require('http').createServer(app)
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!")
})
//Socket Logic
const socketio = require('socket.io')(http)
socketio.on("connection", (userSocket) => {
userSocket.on("send_message", (data) => {
userSocket.broadcast.emit("receive_message", data)
})
})
http.listen(process.env.PORT)
연결 이벤트는 소켓이 앱에 연결될 때마다 트리거됩니다. 그런 다음 수신된 모든 데이터를 receive_message 이벤트로 전달하는 send_message 이벤트에 수신기를 추가합니다.
짜잔!! 백엔드가 준비되었습니다. heroku에 배포한 다음 Flutter 앱을 시작할 수 있습니다.
빠른 참고: 다음은 이벤트를 보내고 받는 방법입니다.
Heroku(배포)
Heroku는 URL을 통해 어디서나 액세스할 수 있도록 앱을 배포하는 클라우드 플랫폼입니다. 시작하자.
앱을 배포하기 전에 몇 가지만 변경하면 됩니다.
const app = require('express')()
const http = require('http').createServer(app)
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!")
})
http.listen(8080)
const app = require('express')()
const http = require('http').createServer(app)
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!")
})
//Socket Logic
const socketio = require('socket.io')(http)
socketio.on("connection", (userSocket) => {
userSocket.on("send_message", (data) => {
userSocket.broadcast.emit("receive_message", data)
})
})
http.listen(process.env.PORT)
Heroku는 URL을 통해 어디서나 액세스할 수 있도록 앱을 배포하는 클라우드 플랫폼입니다. 시작하자.
앱을 배포하기 전에 몇 가지만 변경하면 됩니다.
http.listen(process.env.PORT)
web: node index.js
/node_modules
heroku login
로그인하라는 메시지가 표시됩니다. 자격 증명을 입력하면 준비가 완료됩니다. heroku create <your-app-name-here>
git init
git add .
git commit -m "Initial Commit"
git push heroku master
완료될 때까지 기다리십시오. 생성된 URL로 이동하면 이전과 동일한 메시지를 볼 수 있습니다.
참고: 생성될 자신의 URL을 사용하십시오.
Flutter(클라이언트 측)
이제 백엔드 부분이 완성되었으며 이제 Flutter에서 채팅 앱을 만들기 시작할 때입니다.
터미널을 열고 다음 명령을 입력하여 Flutter 앱을 만듭니다.
flutter create --androidx real_chat_flutter
프로젝트가 생성된 후 IDE에서 폴더를 엽니다.
pubspec.yaml 파일에서 다음 종속성을 추가합니다.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
flutter_socket_io: ^0.6.0 //Add this dependency
lib 폴더에서 main.dart를 열고 모든 코드를 삭제하고 다음 코드를 추가합니다.
import 'package:flutter/material.dart';
import './ChatPage.dart';
void main() => runApp(MyMaterial());
class MyMaterial extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: ChatPage(),
);
}
}
이제 ChatPage를 만들어야 합니다. lib 폴더 안에 ChatPage.dart 파일을 생성합니다. 채팅 페이지의 코드를 작성해 보겠습니다.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_socket_io/flutter_socket_io.dart';
import 'package:flutter_socket_io/socket_io_manager.dart';
class ChatPage extends StatefulWidget {
@override
_ChatPageState createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
SocketIO socketIO;
List<String> messages;
double height, width;
TextEditingController textController;
ScrollController scrollController;
@override
void initState() {
//Initializing the message list
messages = List<String>();
//Initializing the TextEditingController and ScrollController
textController = TextEditingController();
scrollController = ScrollController();
//Creating the socket
socketIO = SocketIOManager().createSocketIO(
'<ENTER THE URL OF YOUR DEPLOYED APP>',
'/',
);
//Call init before doing anything with socket
socketIO.init();
//Subscribe to an event to listen to
socketIO.subscribe('receive_message', (jsonData) {
//Convert the JSON data received into a Map
Map<String, dynamic> data = json.decode(jsonData);
this.setState(() => messages.add(data['message']));
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 600),
curve: Curves.ease,
);
});
//Connect to the socket
socketIO.connect();
super.initState();
}
Widget buildSingleMessage(int index) {
return Container(
alignment: Alignment.centerLeft,
child: Container(
padding: const EdgeInsets.all(20.0),
margin: const EdgeInsets.only(bottom: 20.0, left: 20.0),
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(20.0),
),
child: Text(
messages[index],
style: TextStyle(color: Colors.white, fontSize: 15.0),
),
),
);
}
Widget buildMessageList() {
return Container(
height: height * 0.8,
width: width,
child: ListView.builder(
controller: scrollController,
itemCount: messages.length,
itemBuilder: (BuildContext context, int index) {
return buildSingleMessage(index);
},
),
);
}
Widget buildChatInput() {
return Container(
width: width * 0.7,
padding: const EdgeInsets.all(2.0),
margin: const EdgeInsets.only(left: 40.0),
child: TextField(
decoration: InputDecoration.collapsed(
hintText: 'Send a message...',
),
controller: textController,
),
);
}
Widget buildSendButton() {
return FloatingActionButton(
backgroundColor: Colors.deepPurple,
onPressed: () {
//Check if the textfield has text or not
if (textController.text.isNotEmpty) {
//Send the message as JSON data to send_message event
socketIO.sendMessage(
'send_message', json.encode({'message': textController.text}));
//Add the message to the list
this.setState(() => messages.add(textController.text));
textController.text = '';
//Scrolldown the list to show the latest message
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 600),
curve: Curves.ease,
);
}
},
child: Icon(
Icons.send,
size: 30,
),
);
}
Widget buildInputArea() {
return Container(
height: height * 0.1,
width: width,
child: Row(
children: <Widget>[
buildChatInput(),
buildSendButton(),
],
),
);
}
@override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(height: height * 0.1),
buildMessageList(),
buildInputArea(),
],
),
),
);
}
}
이제 두 기기에서 앱을 실행하고 주고받으며 채팅하세요😄.
문제가 발생하면 내 github repo를 확인할 수 있습니다.
ibtesam123
/
real_chat_node
ibtesam123
/
real_chat_flutter
기사가 마음에 든다면 별표 ⭐ 레포와 박수 👏를 잊지 마세요. 궁금하신 사항은 댓글로 물어보시면 됩니다. 감사합니다😄
Reference
이 문제에 관하여(실시간 채팅 앱 - Flutter, Node.js 및 Socket.io), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/ibtesam123/realtime-chat-app-flutter-node-js-socket-io-em7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
flutter_socket_io: ^0.6.0 //Add this dependency
import 'package:flutter/material.dart';
import './ChatPage.dart';
void main() => runApp(MyMaterial());
class MyMaterial extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: ChatPage(),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_socket_io/flutter_socket_io.dart';
import 'package:flutter_socket_io/socket_io_manager.dart';
class ChatPage extends StatefulWidget {
@override
_ChatPageState createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
SocketIO socketIO;
List<String> messages;
double height, width;
TextEditingController textController;
ScrollController scrollController;
@override
void initState() {
//Initializing the message list
messages = List<String>();
//Initializing the TextEditingController and ScrollController
textController = TextEditingController();
scrollController = ScrollController();
//Creating the socket
socketIO = SocketIOManager().createSocketIO(
'<ENTER THE URL OF YOUR DEPLOYED APP>',
'/',
);
//Call init before doing anything with socket
socketIO.init();
//Subscribe to an event to listen to
socketIO.subscribe('receive_message', (jsonData) {
//Convert the JSON data received into a Map
Map<String, dynamic> data = json.decode(jsonData);
this.setState(() => messages.add(data['message']));
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 600),
curve: Curves.ease,
);
});
//Connect to the socket
socketIO.connect();
super.initState();
}
Widget buildSingleMessage(int index) {
return Container(
alignment: Alignment.centerLeft,
child: Container(
padding: const EdgeInsets.all(20.0),
margin: const EdgeInsets.only(bottom: 20.0, left: 20.0),
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(20.0),
),
child: Text(
messages[index],
style: TextStyle(color: Colors.white, fontSize: 15.0),
),
),
);
}
Widget buildMessageList() {
return Container(
height: height * 0.8,
width: width,
child: ListView.builder(
controller: scrollController,
itemCount: messages.length,
itemBuilder: (BuildContext context, int index) {
return buildSingleMessage(index);
},
),
);
}
Widget buildChatInput() {
return Container(
width: width * 0.7,
padding: const EdgeInsets.all(2.0),
margin: const EdgeInsets.only(left: 40.0),
child: TextField(
decoration: InputDecoration.collapsed(
hintText: 'Send a message...',
),
controller: textController,
),
);
}
Widget buildSendButton() {
return FloatingActionButton(
backgroundColor: Colors.deepPurple,
onPressed: () {
//Check if the textfield has text or not
if (textController.text.isNotEmpty) {
//Send the message as JSON data to send_message event
socketIO.sendMessage(
'send_message', json.encode({'message': textController.text}));
//Add the message to the list
this.setState(() => messages.add(textController.text));
textController.text = '';
//Scrolldown the list to show the latest message
scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 600),
curve: Curves.ease,
);
}
},
child: Icon(
Icons.send,
size: 30,
),
);
}
Widget buildInputArea() {
return Container(
height: height * 0.1,
width: width,
child: Row(
children: <Widget>[
buildChatInput(),
buildSendButton(),
],
),
);
}
@override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(height: height * 0.1),
buildMessageList(),
buildInputArea(),
],
),
),
);
}
}
Reference
이 문제에 관하여(실시간 채팅 앱 - Flutter, Node.js 및 Socket.io), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ibtesam123/realtime-chat-app-flutter-node-js-socket-io-em7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)