Ngày nay, ứng dụng công nghệ và việc tin học hóa được xem là một trong những yếu tố mang tính quyết định trong hoạt động của các chính phủ, tổ chức, cũng như của các công ty, nó đóng vai trò hết sức quan trọng, có thể tạo ra những bước đột phá mạnh mẽ. Với sự phát triển ngày càng nhanh chóng này của xã hội thì việc phát triển hệ thống mạng lưới thông tin là một điều kiện tiên quyết.Và khi hệ thống mạng lưới thông tin được phủ sóng rộng rãi, chúng ta chắc chắn sẽ thực hiện được nhiều công việc, truyền thông tin, dữ liệu với tốc độ nhanh hơn và chi phí thấp hơn nhiều so với cách thức truyền thống.
Mai Tuấn Việt TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI KHOA ĐIỆN - ĐIỆN TỬ BỘ MÔN KỸ THUẬT VIỄN THÔNG - - NGHIÊN CỨU PHÁT TRIỂN ỨNG DỤNG CHAT CHO HỆ THỐNG THÔNG TIN DI ĐỘNG ĐỒ ÁN TỐT NGHIỆP NGHIÊN CỨU PHÁT TRIỂN ỨNG DỤNG CHAT CHO HỆ THỐNG THÔNG TIN DI ĐỘNG Sinh viên thực hiện: Mai Tuấn ViệtLớp: Khóa:Kỹ thuật viễn thơng 56Giáo viên hướng dẫn: TS Trần Hoài Trung HÀ NỘI - 2019 Năm 2020 s TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI KHOA ĐIỆN - ĐIỆN TỬ BỘ MÔN KỸ THUẬT VIỄN THÔNG - - ĐỒ ÁN TỐT NGHIỆP NGHIÊN CỨU PHÁT TRIỂN ỨNG DỤNG CHAT CHO HỆ THỐNG THÔNG TIN DI ĐỘNG Sinh viên thực hiện: Lớp: Mai Tuấn Việt Kỹ thuật viễn thơng Khóa: Giáo viên hướng dẫn: 56 TS Trần Hoài Trung HÀ NỘI - 2019 BỘ GIÁO DỤC VÀ ĐÀO TẠO CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM TRƯỜNG ĐẠI HỌC GTVT Độc lập - Tự - Hạnh phúc NHIỆM VỤ ĐỒ ÁN TỐT NGHIỆP BỘ MÔN KỸ THUẬT VIỄN THÔNG KHOA ĐIỆN - ĐIỆN TỬ LỜI CAM ĐOAN Cam đoan không chép từ đồ án, luận văn khác Các nội dung, liệu tham khảo trích dẫn đầy đủ … Người cam đoan Mai Tuấn Việt LỜI NÓI ĐẦU I Tính cấp thiết đề tài: Ngày nay, ứng dụng cơng nghệ việc tin học hóa xem yếu tố mang tính định hoạt động phủ, tổ chức, cơng ty, đóng vai trò quan trọng, tạo bước đột phá mạnh mẽ Với phát triển ngày nhanh chóng xã hội việc phát triển hệ thống mạng lưới thông tin điều kiện tiên quyết.Và hệ thống mạng lưới thông tin phủ sóng rộng rãi, chắn thực nhiều công việc, truyền thông tin, liệu với tốc độ nhanh chi phí thấp nhiều so với cách thức truyền thống Chính điều này, thúc đẩy khai sinh phát triển ứng dụng Chat - ứng dụng truyền thông giúp cho việc truyền thông tin trở nên dễ dàng tiết kiệm hơn, nhanh chóng hơn, làm biến đổi đáng kể mặt văn hóa, nâng cao chất lượng sống người II Đối tượng phạm vi nghiên cứu: Nghiên cứu phát triển ứng dụng chat tảng phổ biến android ios III Phương pháp nghiên cứu: - Sử dụng kiến thức học tài liệu có liên quan nước liên quan đến đề tài nghiên cứu đặc biệt tài liệu phát triển ứng dụng , thiết kế hệ thống hệ thống thông tin di động - Nghiên cứu tìm hiểu tập trung bám sát đề cương hướng dẫn Thầy giáo IV Mục tiêu nghiên cứu đề tài: Nghiên cứu phát triển thành công để ứng dụng truyền thơng tin trực thời gian thực chạy ổn định tảng android ios V Kết cấu đề tài: Chương Giới thiệu hệ thống chat công nghệ phục vụ cho việc lập trình hệ thống Chương Phân tích giao thức truyền dẫn thông tin hệ thống thông tin di động Chương Phân tích chi tiết thiết kế hệ thống Hà Nội, ngày … tháng … năm 2019 Sinh viên thực Mai Tuấn Việt MỤC LỤC TỜ GIAO NHIỆM VỤ ĐỒ ÁN TỐT NGHIỆP LỜI CAM ĐOAN LỜI CAM ĐOAN LỜI NÓI ĐẦU LỜI NÓI ĐẦU DANH MỤC HÌNH VẼ DANH MỤC HÌNH VẼ DANH MỤC KÝ HIỆU, THUẬT NGỮ VIẾT TẮT .10 DANH MỤC KÝ HIỆU, THUẬT NGỮ VIẾT TẮT .10 CHƯƠNG GIỚI THIỆU VỀ HỆ THỐNG CHAT VÀ CÁC CÔNG NGHỆ PHỤC VỤ CHO VIỆC LẬP TRÌNH HỆ THỐNG 11 CHƯƠNG GIỚI THIỆU VỀ HỆ THỐNG CHAT VÀ CÁC CƠNG NGHỆ PHỤC VỤ CHO VIỆC LẬP TRÌNH HỆ THỐNG 11 1.1 Giới thiệu chung hệ thống chat .12 1.1 Giới thiệu chung hệ thống chat .12 1.2 Giới thiệu công nghệ sử dụng cho hệ thống chat 13 1.2 Giới thiệu công nghệ sử dụng cho hệ thống chat 13 1.2.1 Ngôn ngữ javascript 13 1.2.2 Công nghệ React Native 15 1.2.3 FireBase 16 1.3 Kết luận chương 24 1.3 Kết luận chương 24 CHƯƠNG PHÂN TÍCH CÁC GIAO THỨC TRUYỀN DẪN THƠNG TIN TRONG HỆ THỐNG THÔNG TIN DI ĐỘNG .25 CHƯƠNG PHÂN TÍCH CÁC GIAO THỨC TRUYỀN DẪN THÔNG TIN TRONG HỆ THỐNG THÔNG TIN DI ĐỘNG .25 2.1 Các giao thức truyền dẫn thông tin hệ thống thông tin di động 26 2.1 Các giao thức truyền dẫn thông tin hệ thống thông tin di động 26 2.2 Sơ đồ, giao thức kết nối sử dụng hệ thống Chat 35 2.2 Sơ đồ, giao thức kết nối sử dụng hệ thống Chat 35 2.3 Kết luận chương 44 6 2.3 Kết luận chương 44 CHƯƠNG 3: PHÂN TÍCH DỮ LIỆU VÀ THIẾT KẾ HỆ THỐNG 45 CHƯƠNG 3: PHÂN TÍCH DỮ LIỆU VÀ THIẾT KẾ HỆ THỐNG 45 3.1 Cài đặt thiết kế sở liệu 46 3.1 Cài đặt thiết kế sở liệu 46 3.1.1 Cài đặt thiết kế sở liệu cho chức đăng ký đăng nhập 46 3.1.2 Cài đặt thiết kế sở liệu cho chức gửi nhận tin nhắn 52 3.1.3 Sơ đồ quản trị 53 3.2 Kiến trúc quản lý liệu 54 3.2 Kiến trúc quản lý liệu 54 3.3 Thiết kế giao diện người dùng 56 3.3 Thiết kế giao diện người dùng 56 3.3.1 Xây dựng hình đăng nhập .56 3.3.2 Xây dựng hình đăng ký : 57 3.3.3 Xây dựng hình chính: 58 3.3.4 Màn hình danh bạ : 59 3.3.5 Xây dựng phòng chat : 60 3.4 Kết luận Chương 60 3.4 Kết luận Chương 60 KẾT LUẬN VÀ KIẾN NGHỊ 62 KẾT LUẬN VÀ KIẾN NGHỊ 62 TÀI LIỆU THAM KHẢO 63 TÀI LIỆU THAM KHẢO 63 PHỤ LỤC 64 PHỤ LỤC 64 DANH MỤC HÌNH VẼ HÌNH 1.1 XU HƯỚNG SỬ DỤNG FIREBASE 17 HÌNH 1.2 CÁC DỊCH VỤ CỦA FIREBASE 18 HÌNH 1.3 MƠ PHỎNG DỮ LIỆU CỦA CƠ SỞ DỮ LIỆU TRÊN FIREBASE 19 HÌNH 1.4 FIREBASE VÀ CÁC THIẾT BỊ HỖ TRỢ 19 HÌNH 1.5 CÁC HÌNH THỨC HỖ TRỢ XÁC THỰC CỦA NGƯỜI DÙNG 20 HÌNH 1.6 MƠ PHỎNG DỮ LIỆU TỪ FIREBASE TỚI CÁC THIẾT BỊ 21 HÌNH 1.7 CHỨC NĂNG ĐỒNG BỘ CẤU HÌNH TRONG FIREBASE .23 HÌNH 2.1 CÁC GIAO THỨC TRUYỀN DẪN THƠNG TIN 26 HÌNH 2.2 MƠ PHỎNG HOẠT ĐỘNG TRUYỀN DẪN THƠNG TIN .27 HÌNH 2.3 GIAO THỨC TCP 29 HÌNH 2.4 SƠ ĐỒ HOẠT ĐỘNG CỦA HTTP .30 HÌNH 2.5 GIAO THỨC SSH 31 HÌNH 2.6 GIAO THỨC SMTP .32 HÌNH 2.7 GIAO THỨC TCP/IP .33 HÌNH 2.8 GIAO THỨC BẮT TAY CỦA WEBSOCKET .37 HÌNH 2.8 SƠ ĐỒ DỮ LIỆU CỦA WEBSOCKET 39 HÌNH 2.9 MƠ HÌNH DỮ LIỆU TRONG FIRESTORE .41 HÌNH 2.10 SƠ ĐỒ CẤU TRÚC ỨNG DỤNG CHAT 42 HÌNH 2.11 SƠ ĐỒ HOẠT ĐỘNG GIỮA PHÍA MÁY KHÁCH VÀ MÁY CHỦ 43 HÌNH 3.1 SƠ ĐỒ LUỒNG DỮ LIỆU XÁC THỰC TRONG FIREBASE 47 HÌNH 3.2 GIAO DIỆN HƯỚNG DẪN KẾT NỐI ỨNG DỤNG VỚI FIREBASE 48 HÌNH 3.3 GIAO DIỆN TẠO CƠ SỞ DỮ LIỆU 49 HÌNH 3.4 BẢNG LỰA CHỌN KIỂU XÁC THỰC TRONG FIREBASE 49 HÌNH 3.5 MÀN HÌNH CẤU HÌNH FIREBASE CHO ỨNG DỤNG 50 HÌNH 3.6 BẢNG LƯU TRỮ THƠNG TIN ĐĂNG NHẬP CỦA NGƯỜI DÙNG.51 HÌNH 3.7 BẢNG LƯU TRỮ TIN NHẮN CỦA NGƯỜI DÙNG 53 HÌNH 3.8 SƠ ĐỒ VAI TRỊ CỦA QUẢN TRỊ VIÊN VÀ NGƯỜI DÙNG 53 HÌNH 3.9 SƠ ĐỒ KIẾN TRÚC DỮ LIỆU REDUX 54 HÌNH 3.10 SƠ ĐỒ DỮ LIỆU CỦA STORE TRONG REDUX 56 HÌNH 3.11 MÀN HÌNH ĐĂNG NHẬP 56 HÌNH 3.12 MÀN HÌNH ĐĂNG KÝ .57 HÌNH 3.13 MÀN HÌNH CHÍNH 58 HÌNH 3.14 MÀN HÌNH DANH BẠ 59 HÌNH 3.15 MÀN HÌNH PHỊNG CHAT .60 buttonSubmit: { alignItems: 'center', justifyContent: 'center', width: '80%', height: 60, backgroundColor: '#495C83', alignSelf: 'center', marginTop: 60, borderRadius: 5, }, submit: { color: 'white', fontSize: 20, fontWeight: '500', }, wings: { height: '100%', width: '15%', alignItems: 'center', justifyContent: 'center', backgroundColor: 'transparent', }, buttonBack: { width: 50, height: 50, alignItems: 'center', justifyContent: 'center', }, }); export default Register; Mã thực giao diện hình người dùng trò chuyện gần : import React, {Fragment, useCallback, useMemo, useEffect} from 'react'; import { StyleSheet, View, Text, StatusBar, Image, TextInput, FlatList, SafeAreaView, } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; import {useSelector} from 'react-redux'; import {sSetProfile} from ' /selectors'; 71 import {search, avatar} from ' /images/index'; import {TouchableOpacity} from 'react-native-gesture-handler'; import AsyncStorage from '@react-native-community/async-storage'; export const Header = (props: any) => { return ( {props.Title} ); }; const Recent = (props: any) => { const url = useSelector(sSetProfile); const _JoinChat = useCallback(() => { console.log('hello'); props.navigation.navigate('Chat'); }, []); const list = []; for (let i = 0; i < 1; i++) { list[i] = {}; list[i].name = `name${[i]}`; list[i].content = `content${[i]}`; } const _renderTask = ({index, item}) => { return ( {item.name} {item.content} ); }; return ( 72 index.toString()} /> ); }; const styles = StyleSheet.create({ container: { width: '100%', height: '100%', // alignItems: 'center', backgroundColor: 'transparent', // position: 'absolute', // transform: [ // {perspective: 850}, // {translateX: -Dimensions.get('window').width * 0.24}, //0 // {rotateY: '60deg'}, //60deg // ], }, behindContainer: { width: '100%', height: '100%', backgroundColor: 'pink', }, header: { width: '100%', height: '20%', backgroundColor: 'transparent', }, flatlist: { flex: 1, backgroundColor: 'transparent', marginTop: 20, }, itemFlatlist: { backgroundColor: 'rgba(73,92,131,0.5)', width: '85%', height: 80, alignItems: 'center', alignSelf: 'center', marginTop: 10, borderRadius: 12, flexDirection: 'row', }, textItems: { marginLeft: 20, }, 73 viewTitle: { backgroundColor: '#495C83', flexDirection: 'row', width: '100%', height: '80%', alignItems: 'center', paddingHorizontal: 25, }, title: { marginTop: 25, fontSize: 28, fontWeight: '500', marginLeft: 10, color: 'white', }, viewTextInput: { width: '90%', height: 35, backgroundColor: '#495C83', flexDirection: 'row', alignItems: 'center', borderRadius: 10, paddingHorizontal: 10, marginLeft: 20, marginTop: 5, }, viewSearch: { width: '10%', height: '100%', alignItems: 'center', justifyContent: 'center', }, TextInput: { height: '100%', width: '100%', fontSize: 14, }, ViewAvatar: { marginLeft: 10, width: 50, height: 50, borderRadius: 10, backgroundColor: 'white', }, }); export default Recent; 74 Chương trình thực giao diện hình danh bạ người dùng : import React, {Fragment, useCallback, useEffect, useMemo} from 'react'; import {icon, background6} from ' /images/index'; import { SafeAreaView, StyleSheet, SectionList, View, Text, StatusBar, Image, ImageBackground, } from 'react-native'; import {Header} from './Recent'; import {useSelector} from 'react-redux'; import {sSetProfile} from ' /selectors'; const SectionListItem = ({item}) => { return ( {item} ); }; let data = [ { name: 'Viet', }, { name: 'Tuan', }, { name: 'Anh', }, { name: 'Quang', }, { name: 'Duy', }, { name: 'Phuc', }, { name: 'Phong', }, { name: 'Tu', }, { name: 'Binh', 75 }, { name: }, { name: }, { name: }, { name: }, { name: }, ]; 'Quan', 'Vu', 'Hieu', 'Nhi', 'Thanh', const Contact = (props: any) => { // for (let i = 0; i < data.length; i++) { // data[i].name.charAt(0).toUpperCase(); // } //mang nhap vao viet thuong const sectionListData = useMemo(() => { let newData = data.sort(function(a, b) { { if (a.name < b.name) { return -1; } if (a.name > b.name) { return 1; } return 0; } }); const sectionListData: {title: string; data: string[]}[] = []; for (let i = 0; i < data.length; i++) { sectionListData[i] = { title: newData[i].name.charAt(0), data: [], }; } const duplicate: string[] = []; for (let i = 0; i < sectionListData.length; i++) { sectionListData[i].data = []; if (!duplicate.includes(sectionListData[i].title)) { duplicate.push(sectionListData[i].title); } else { sectionListData.splice(i, 1); i ; } } 76 for (let i = 0; i < data.length; i++) { for (let j = 0; j < sectionListData.length; j++) { if (data[i].name.charAt(0) == sectionListData[j].title) { sectionListData[j].data.push(data[i].name); } } } return sectionListData; }, [data]); const _renderItems = useCallback(({item}) => { return ; }, []); const _renderSections = useCallback( ({section: {title}}) => ( {title} ), [], ); const url = useSelector(sSetProfile); return ( index.toString()} /> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'white', }, viewSections: { backgroundColor: '#495C83', width: '90%', height: 30, 77 alignSelf: 'center', borderRadius: 5, marginBottom: 10, justifyContent: 'center', }, viewItems: { width: '90%', height: 70, alignItems: 'center', justifyContent: 'center', alignSelf: 'center', borderRadius: 8, backgroundColor: 'rgba(73,92,131,0.5)', marginBottom: 10, }, }); export default Contact; Chương trình thực giao diện hình hiển thơng tin người dùng : import React, {useState, useCallback} from 'react'; import {icon} from ' /images/index'; import { SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar, Image, ImageBackground, TextInput, TouchableOpacity, } from 'react-native'; import {useSelector, useDispatch} from 'react-redux'; import {sSetProfile} from ' /selectors'; import Icon from 'react-native-vector-icons/MaterialIcons'; import Icon2 from 'react-native-vector-icons/FontAwesome'; import ImagePicker from 'react-native-image-picker'; import {avatar} from ' /images/index'; import {setAvatarAction} from ' /redux/actions/profile-action'; const options = { title: 'Select Avatar', storageOptions: { skipBackup: true, path: 'images', }, 78 quality: '0.05', }; const Profile = (props: any) => { const dispatch = useDispatch(); const [Avatar, ChangeAvatar] = useState(avatar); const url = useSelector(sSetProfile); // useEffect(() => { // dispatch(getNotificationAction()); // }, []); // const list = useMemo(() => { // const list = []; // data && // data.forEach(value => { // const object = { // title: value.get('message'), // time: value.get('sendDateTime'), // id: value.get('senderId'), // }; // list.push(object); // }); // return list; // }, [data]); const _changeAvatar = useCallback(() => { ImagePicker.showImagePicker(options, response => { if (response.didCancel) { console.log('User cancelled image picker'); } else { console.log(response); // You can also display the image using data: const source = {uri: 'data:image/jpeg;base64,' + response.data}; ChangeAvatar(source); dispatch(setAvatarAction(source)); } }); }, []); return ( User Profile ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'white', }, viewTitle: { width: '100%', height: '40%', }, title: { backgroundColor: '#495C83', alignItems: 'center', width: '100%', height: '80%', }, viewAvatar: { overflow: 'hidden', marginTop: '23.5%', width: 100, height: 100, backgroundColor: 'gray', borderRadius: 50, }, header: { width: '100%', height: '35%', flexDirection: 'row', alignItems: 'flex-end', justifyContent: 'center', }, viewContent: { flex: 1, padding: 30, }, line: { width: '100%', height: 35, backgroundColor: 'transparent', 80 flexDirection: 'row', borderBottomWidth: 1, }, avatarBackground: { width: 100, height: 100, alignSelf: 'center', justifyContent: 'flex-end', alignItems: 'center', }, avatar: { width: '100%', height: '37%', backgroundColor: 'rgba(28,28,28,0.6)', alignItems: 'center', justifyContent: 'center', }, }); export default Profile; Chương trình thực giao diện hình phòng : import React, {useState, useCallback, useEffect, useMemo} from 'react'; import { StyleSheet, View, Text, TouchableOpacity, StatusBar, TextInput, KeyboardAvoidingView, FlatList, } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import Icon from 'react-native-vector-icons/FontAwesome'; import {NavigationActions} from 'react-navigation'; const ChatLine = (props: any) => { return ( {props.item.email} {props.item.chatContent} ); }; const const const const const Chat = (props: any) => { [email, setEmail] = useState(); [chatContent, setChatContent] = useState(''); [data, setData] = useState([] as any[]); _send = useCallback(() => { 81 setData(old => old.concat({email: email, chatContent: chatContent})); }, [data, email, chatContent]); const _input = useCallback( text => { setChatContent(text); }, [chatContent], ); useEffect(() => { getitemsAsyncStorage; }, [data]); const getitemsAsyncStorage = useMemo(async () => { try { const email = await AsyncStorage.getItem('email'); console.log(email); return setEmail(email); } catch (error) { throw error; } }, []); const _back = useCallback(() => { props.navigation.goBack(); }, []); const _renderItems = useCallback(({item, index}) => { return ; }, []); return ( Chat room index.toString()} renderItem={_renderItems}> 82 Send ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'rgba(73,92,131,0.3)', }, header: { width: '100%', height: '10%', backgroundColor: '#495C83', flexDirection: 'row', }, title: { color: 'white', fontSize: 20, fontWeight: '600', marginBottom: 10, }, bottom: { width: '100%', height: '10%', backgroundColor: '#495C83', alignItems: 'center', flexDirection: 'row', }, textInput: { width: '80%', height: '100%', paddingLeft: 20, fontSize: 18, color: 'white', }, send: { width: '20%', height: '100%', backgroundColor: '#495C83', borderLeftWidth: 1, borderColor: 'white', alignItems: 'center', justifyContent: 'center', }, chatLineContainer: { // alignSelf: 'flex-end', flexDirection: 'column', maxWidth: '70%', 83 alignItems: 'flex-start', padding: 8, backgroundColor: 'white', marginVertical: 10, marginHorizontal: 10, borderRadius: 5, }, viewTitle: { height: '100%', width: '70%', alignItems: 'center', justifyContent: 'flex-end', }, wings: { height: '100%', width: '15%', alignItems: 'center', justifyContent: 'flex-end', padding: 10, }, sender: {fontSize: 17, marginBottom: 8, color: '#495C83', fontWeight: 'bold'}, }); export default Chat; Chương trình hàm xử lý liệu: Action: export const setAvatarAction = createTypeAction('SET_AVATAR'); Reducer: import {createTypeReducer} from ' / /redux-type-saga'; import {setAvatarAction} from ' /actions/profile-action'; import {IImutableProfileState} from ' / /redux-state'; import {fromJS} from 'immutable'; import {avatar} from ' / /images/index'; export function createInitProfileState(): IImutableProfileState { return fromJS({ url: avatar, }); } const setAvatar = setAvatarAction.reducer( (state, action) => { return state.set('url', action.payload); }, ); const profileReducer = createTypeReducer( 84 createInitProfileState(), setAvatar, ); export default profileReducer; Store: import import import import import {createStore, applyMiddleware, compose} from 'redux'; {combineReducers} from 'redux-immutable'; {Record} from 'immutable'; createSagaMiddleware from 'redux-saga'; {IStore} from ' /redux-state'; import profileReducer from './reducer/profile-reducer'; import {createInitProfileState} from './reducer/profile-reducer'; export const InitialState = Record({ profileState: createInitProfileState(), })(); export const rootReducer = combineReducers( { profileState: profileReducer, }, InitialState, ); export const configureStore = (initialStateMap = InitialState) => { const initialState = Record({ profileState: initialStateMap.profileState || createInitProfileState(), })(); return createStore(rootReducer, initialState); }; export const store = configureStore(); Selector: import {REDUX_TYPE} from './redux-type-saga'; import {IImmutableMap} from './global/interface'; export const sSetProfile = (store: any) => store.profileState.get('url'); 85