生活随笔
收集整理的這篇文章主要介紹了
即时通讯源码|IM源码PHP
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
即時通訊源碼是一個完整的消息傳遞套件,供企業構建跨 Web、Android、iOS 設備的可定制協作平臺,以建立虛擬連接。即時通訊解決方案提供多種通信媒介,如語音和視頻通話、實時聊天、視頻會議,以連接來自多個設備的遠程團隊。即時通訊源碼提供功能豐富的 API 和 SDK,以在任何應用程序上集成通信平臺。企業消息傳遞解決方案能夠擁有大約 1M+ 的并發用戶群。即時通訊源碼兼容端到端加密、信號協議、AES-256 位和其他隱私合規性,如 HIPAA、GDPR、COPAA,以保護整個對話。
演示:im.jstxym.top
技術棧:
MongoDB
Express
React
Node
除了上述技術之外,我還使用TypeScript來提高我的代碼的健壯性,并使用Redux來管理應用程序狀態。
我還應該提到socket.io,它支持瀏覽器和服務器之間的實時、雙向和基于事件的通信。
對于部署,一種簡單有效的方法是將前端托管在Netlify上,后端托管在云平臺上。
以下是我通常用來增強編程體驗的工具列表:
操作系統:MacOS
終端:iterm2
IDE:VSCode
版本控制:Git
包管理器:NPM
項目組織:Notion
線框和設計
老實說,我對設計產品的 UI 并沒有太多的樂趣。因此,我決定使用現有的線框并專注于代碼。
快速概覽:
數據建模和 API 路由
數據庫設計和 API 路由是重要的步驟。在開始編碼之前確保你有一個行動計劃,否則這將是一場災難
這是一個使用Lucidchart制作的簡單數據模型:
確實很簡單,但是對于這個項目來說已經足夠了。
正如您可能猜到的,我們正在使用 Node/Express 構建一個涉及 HTTP 請求的 REST API。
即時通訊源碼項目組織
步驟 01:設置和前端
開始編碼總是那么令人興奮,這是我最喜歡的過程。我從設置前端和后端開始,這意味著安裝依賴項、環境變量、CSS 重置、創建數據庫......設置完成后,我構建了應該出現在屏幕上的每一個組件,并確保它們對移動設備友好。
說到組件和 UI,這里有一個簡單的例子:
// TopBar/index.tsx
import React from 'react';
import { IconButton } from '@material-ui/core';
import MenuIcon from '@material-ui/icons/Menu';// Local Imports
import styles from './styles.module.scss';type Props = {title?: String;menuClick: () => void;
};const TopBar: React.FC<Props> = props => {return (<div className={styles.container}><div className={styles.wrapper}><IconButton className={styles.iconButton} onClick={props.menuClick}><MenuIcon className={styles.menu} fontSize="large" /></IconButton><h2 className={styles.title}>{props.title}</h2></div></div>);
};export default TopBar;// TopBar/styles.module.scss
.container {width: 100%;height: 60px;box-shadow: 0px 4px 4px rgba($color: #000, $alpha: 0.2);display: flex;align-items: center;justify-content: center;
}.wrapper {width: 95%;display: flex;align-items: center;
}.title {font-size: 18px;
}.iconButton {display: none !important;@media (max-width: 767px) {display: inline-block !important;}
}.menu {color: #e0e0e0;
}
沒什么特別的,它是TypeScript和SCSS模塊的基本實現。我非常喜歡SCSS,并為所有感興趣的人寫了一個介紹:您還可以注意到,一些組件(圖標、輸入等)是從我最喜歡的 UI 庫中導入的:Material UI。說到TypeScript,最初的日子真的很痛苦和累,但到最后,在開發過程中發現 bug 似乎非常容易。
我使用的另一個很酷的工具是Formik,它以一種智能且簡單的方式管理表單驗證。
// Login/index.tsximport React, { useState } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { TextField, FormControlLabel, Checkbox, Snackbar, CircularProgress } from '@material-ui/core';
import MuiAlert from '@material-ui/lab/Alert';
import { useDispatch } from 'react-redux';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { useHistory } from 'react-router-dom';// Local Imports
import logo from '../../../assets/gc-logo-symbol-nobg.png';
import CustomButton from '../../Shared/CustomButton/index';
import styles from './styles.module.scss';type Props = {};type SnackData = {open: boolean;message: string | null;
};const Login: React.FC<Props> = props => {const dispatch = useDispatch();const history = useHistory();const [isLoading, setIsLoading] = useState(false);const [checked, setChecked] = useState(false);const [snack, setSnack] = useState<SnackData>({ open: false, message: null });// Async Requestsconst loginSubmit = async (checked: boolean, email: string, password: string) => {setIsLoading(true);let response;try {response = await axios.post(`${process.env.REACT_APP_SERVER_URL}/users/login`, {checked,email: email.toLowerCase(),password: password.toLowerCase()});} catch (error) {console.log('[ERROR][AUTH][LOGIN]: ', error);setIsLoading(false);return;}if (!response.data.access) {setSnack({ open: true, message: response.data.message });setIsLoading(false);return;}if (checked) {localStorage.setItem('userData', JSON.stringify({ id: response.data.user.id, token: response.data.user.token }));}dispatch({ type: 'LOGIN', payload: { ...response.data.user } });history.push('');setIsLoading(false);};const formik = useFormik({initialValues: {email: '',password: ''},validationSchema: Yup.object({email: Yup.string().email('Invalid email address').required('Required'),password: Yup.string().min(6, 'Must be 6 characters at least').required('Required').max(20, 'Can not exceed 20 characters')}),onSubmit: values => loginSubmit(checked, values.email, values.password)});return (<div className={styles.container}><Link to="/"><img className={styles.logo} alt="logo" src={logo} /></Link><form className={styles.form}><TextFieldclassName={styles.input}id="email"label="Email"variant="outlined"type="text"helperText={formik.touched.email && formik.errors.email}error={formik.touched.email && !!formik.errors.email}{...formik.getFieldProps('email')}/><TextFieldclassName={styles.input}id="password"label="Password"variant="outlined"type="password"{...formik.getFieldProps('password')}helperText={formik.touched.password && formik.errors.password}error={formik.touched.password && !!formik.errors.password}/><FormControlLabelclassName={styles.check}control={<Checkbox checked={checked} onChange={() => setChecked(prev => !prev)} name="checked" color="primary" />}label="Remember me"/><CustomButton type="submit" onClick={formik.handleSubmit} isPurple title="Login" small={false} /></form><Link to="/signup"><p className={styles.guest}>Don't have an account? Sign Up</p></Link>{isLoading && <CircularProgress />}<Snackbar open={snack.open} onClose={() => setSnack({ open: false, message: null })} autoHideDuration={5000}><MuiAlert variant="filled" onClose={() => setSnack({ open: false, message: null })} severity="error">{snack.message}</MuiAlert></Snackbar></div>);
};export default Login;
步驟 02:后端
服務器非常簡單,它是 Node/Express 服務器經典樣式。然后,我注冊了路由并連接了相應的控制器。在我的控制器中,您可以找到經典的 CRUD 操作和一些自定義函數。多虧了JWT,才有可能在安全方面工作,這對我來說很重要。現在是這個應用程序最酷的功能,雙向通信,或者我應該說socket.io嗎?
這是一個例子:
// app.js - Server side// Establish a connection
io.on('connection', socket => {// New usersocket.on('new user', uid => {userList.push(new User(uid, socket.id));});// Join groupsocket.on('join group', (uid, gid) => {for (let i = 0; i < userList.length; i++) {if (socket.id === userList[i].sid) userList[i].gid = gid;}});// New groupsocket.on('create group', (uid, title) => {io.emit('fetch group');});// New messagesocket.on('message', (uid, gid) => {for (const user of userList) {if (gid === user.gid) io.to(user.sid).emit('fetch messages', gid);}});// Close connectionsocket.on('disconnect', () => {for (let i = 0; i < userList.length; i++) {if (socket.id === userList[i].sid) userList.splice(i, 1);}});
});// AppView/index.tsx - Client sideuseEffect(() => {const socket = socketIOClient(process.env.REACT_APP_SOCKET_URL!, { transports: ['websocket'] });socket.emit('new user', userData.id);socket.on('fetch messages', (id: string) => fetchMessages(id));socket.on('fetch group', fetchGroups);setSocket(socket);fetchGroups();}, []);
我發現了express-validator,它在服務器端提供輸入驗證很有幫助。毫無疑問,我將再次使用。
步驟 03:修復和部署
好的,該應用程序看起來不錯,功能運行良好。是時候完成這個投資組合項目并開始一個新的項目了。我不是云解決方案和復雜 CI/CD 方法的專家,所以我會滿足于免費的托管服務。云平臺有一個適用于后端的免費解決方案。我的節點服務器上傳 5 分鐘后,它獨立運行。我在客戶端遇到了一些安全問題。
最后,用戶上傳的圖像通過他們的公共 API存儲在我的云帳戶中。
即時通訊源碼特征:
視頻通話
語音通話
實時消息
現場直播
視頻會議
SIP 和 VoIP 通話
一鍵通
屏幕共享
多通道
端到端加密
自定義身份驗證
以訪客身份登錄
隨機頭像/個人資料圖片上傳
授權(json web 令牌)
端到端輸入驗證
創建和加入頻道
即時消息
結論
我非常享受在這個項目上的工作并學到了很多東西。很高興與您分享這個過程,我迫不及待地想聽到您的提示和反饋。這個項目無非是一個組合項目,代碼開源的,您可以隨意使用它。
總結
以上是生活随笔為你收集整理的即时通讯源码|IM源码PHP的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。