• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

即时通讯源码|IM源码PHP

武飞扬头像
ityuanh
帮助1

  即时通讯源码是一个完整的消息传递套件,供企业构建跨 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,这里有一个简单的例子:

  1.  
    // TopBar/index.tsx
  2.  
    import React from 'react';
  3.  
    import { IconButton } from '@material-ui/core';
  4.  
    import MenuIcon from '@material-ui/icons/Menu';
  5.  
     
  6.  
    // Local Imports
  7.  
    import styles from './styles.module.scss';
  8.  
     
  9.  
    type Props = {
  10.  
    title?: String;
  11.  
    menuClick: () => void;
  12.  
    };
  13.  
     
  14.  
    const TopBar: React.FC<Props> = props => {
  15.  
    return (
  16.  
    <div className={styles.container}>
  17.  
    <div className={styles.wrapper}>
  18.  
    <IconButton className={styles.iconButton} onClick={props.menuClick}>
  19.  
    <MenuIcon className={styles.menu} fontSize="large" />
  20.  
    </IconButton>
  21.  
    <h2 className={styles.title}>{props.title}</h2>
  22.  
    </div>
  23.  
    </div>
  24.  
    );
  25.  
    };
  26.  
     
  27.  
    export default TopBar;
  28.  
     
  29.  
    // TopBar/styles.module.scss
  30.  
    .container {
  31.  
    width: 100%;
  32.  
    height: 60px;
  33.  
    box-shadow: 0px 4px 4px rgba($color: #000, $alpha: 0.2);
  34.  
    display: flex;
  35.  
    align-items: center;
  36.  
    justify-content: center;
  37.  
    }
  38.  
     
  39.  
    .wrapper {
  40.  
    width: 95%;
  41.  
    display: flex;
  42.  
    align-items: center;
  43.  
    }
  44.  
     
  45.  
    .title {
  46.  
    font-size: 18px;
  47.  
    }
  48.  
     
  49.  
    .iconButton {
  50.  
    display: none !important;
  51.  
    @media (max-width: 767px) {
  52.  
    display: inline-block !important;
  53.  
    }
  54.  
    }
  55.  
     
  56.  
    .menu {
  57.  
    color: #e0e0e0;
  58.  
    }
学新通

  没什么特别的,它是TypeScript和SCSS模块的基本实现。我非常喜欢SCSS,并为所有感兴趣的人写了一个介绍:您还可以注意到,一些组件(图标、输入等)是从我最喜欢的 UI 库中导入的:Material UI。说到TypeScript,最初的日子真的很痛苦和累,但到最后,在开发过程中发现 bug 似乎非常容易。
  
  我使用的另一个很酷的工具是Formik,它以一种智能且简单的方式管理表单验证。 

  1.  
    // Login/index.tsx
  2.  
     
  3.  
    import React, { useState } from 'react';
  4.  
    import { Link } from 'react-router-dom';
  5.  
    import axios from 'axios';
  6.  
    import { TextField, FormControlLabel, Checkbox, Snackbar, CircularProgress } from '@material-ui/core';
  7.  
    import MuiAlert from '@material-ui/lab/Alert';
  8.  
    import { useDispatch } from 'react-redux';
  9.  
    import { useFormik } from 'formik';
  10.  
    import * as Yup from 'yup';
  11.  
    import { useHistory } from 'react-router-dom';
  12.  
     
  13.  
    // Local Imports
  14.  
    import logo from '../../../assets/gc-logo-symbol-nobg.png';
  15.  
    import CustomButton from '../../Shared/CustomButton/index';
  16.  
    import styles from './styles.module.scss';
  17.  
     
  18.  
    type Props = {};
  19.  
     
  20.  
    type SnackData = {
  21.  
    open: boolean;
  22.  
    message: string | null;
  23.  
    };
  24.  
     
  25.  
    const Login: React.FC<Props> = props => {
  26.  
    const dispatch = useDispatch();
  27.  
    const history = useHistory();
  28.  
     
  29.  
    const [isLoading, setIsLoading] = useState(false);
  30.  
    const [checked, setChecked] = useState(false);
  31.  
    const [snack, setSnack] = useState<SnackData>({ open: false, message: null });
  32.  
     
  33.  
    // Async Requests
  34.  
    const loginSubmit = async (checked: boolean, email: string, password: string) => {
  35.  
    setIsLoading(true);
  36.  
    let response;
  37.  
    try {
  38.  
    response = await axios.post(`${process.env.REACT_APP_SERVER_URL}/users/login`, {
  39.  
    checked,
  40.  
    email: email.toLowerCase(),
  41.  
    password: password.toLowerCase()
  42.  
    });
  43.  
    } catch (error) {
  44.  
    console.log('[ERROR][AUTH][LOGIN]: ', error);
  45.  
    setIsLoading(false);
  46.  
    return;
  47.  
    }
  48.  
    if (!response.data.access) {
  49.  
    setSnack({ open: true, message: response.data.message });
  50.  
    setIsLoading(false);
  51.  
    return;
  52.  
    }
  53.  
    if (checked) {
  54.  
    localStorage.setItem('userData', JSON.stringify({ id: response.data.user.id, token: response.data.user.token }));
  55.  
    }
  56.  
    dispatch({ type: 'LOGIN', payload: { ...response.data.user } });
  57.  
    history.push('');
  58.  
    setIsLoading(false);
  59.  
    };
  60.  
     
  61.  
    const formik = useFormik({
  62.  
    initialValues: {
  63.  
    email: '',
  64.  
    password: ''
  65.  
    },
  66.  
    validationSchema: Yup.object({
  67.  
    email: Yup.string().email('Invalid email address').required('Required'),
  68.  
    password: Yup.string()
  69.  
    .min(6, 'Must be 6 characters at least')
  70.  
    .required('Required')
  71.  
    .max(20, 'Can not exceed 20 characters')
  72.  
    }),
  73.  
    onSubmit: values => loginSubmit(checked, values.email, values.password)
  74.  
    });
  75.  
     
  76.  
    return (
  77.  
    <div className={styles.container}>
  78.  
    <Link to="/">
  79.  
    <img className={styles.logo} alt="logo" src={logo} />
  80.  
    </Link>
  81.  
    <form className={styles.form}>
  82.  
    <TextField
  83.  
    className={styles.input}
  84.  
    id="email"
  85.  
    label="Email"
  86.  
    variant="outlined"
  87.  
    type="text"
  88.  
    helperText={formik.touched.email && formik.errors.email}
  89.  
    error={formik.touched.email && !!formik.errors.email}
  90.  
    {...formik.getFieldProps('email')}
  91.  
    />
  92.  
    <TextField
  93.  
    className={styles.input}
  94.  
    id="password"
  95.  
    label="Password"
  96.  
    variant="outlined"
  97.  
    type="password"
  98.  
    {...formik.getFieldProps('password')}
  99.  
    helperText={formik.touched.password && formik.errors.password}
  100.  
    error={formik.touched.password && !!formik.errors.password}
  101.  
    />
  102.  
    <FormControlLabel
  103.  
    className={styles.check}
  104.  
    control={
  105.  
    <Checkbox checked={checked} onChange={() => setChecked(prev => !prev)} name="checked" color="primary" />
  106.  
    }
  107.  
    label="Remember me"
  108.  
    />
  109.  
    <CustomButton type="submit" onClick={formik.handleSubmit} isPurple title="Login" small={false} />
  110.  
    </form>
  111.  
    <Link to="/signup">
  112.  
    <p className={styles.guest}>Don't have an account? Sign Up</p>
  113.  
    </Link>
  114.  
    {isLoading && <CircularProgress />}
  115.  
    <Snackbar open={snack.open} onClose={() => setSnack({ open: false, message: null })} autoHideDuration={5000}>
  116.  
    <MuiAlert variant="filled" onClose={() => setSnack({ open: false, message: null })} severity="error">
  117.  
    {snack.message}
  118.  
    </MuiAlert>
  119.  
    </Snackbar>
  120.  
    </div>
  121.  
    );
  122.  
    };
  123.  
     
  124.  
    export default Login;
学新通

  步骤 02:后端
  
  服务器非常简单,它是 Node/Express 服务器经典样式。然后,我注册了路由并连接了相应的控制器。在我的控制器中,您可以找到经典的 CRUD 操作和一些自定义函数。多亏了JWT,才有可能在安全方面工作,这对我来说很重要。现在是这个应用程序最酷的功能,双向通信,或者我应该说socket.io吗?
  
  这是一个例子: 

  1.  
     // app.js - Server side
  2.  
     
  3.  
    // Establish a connection
  4.  
    io.on('connection', socket => {
  5.  
    // New user
  6.  
    socket.on('new user', uid => {
  7.  
    userList.push(new User(uid, socket.id));
  8.  
    });
  9.  
     
  10.  
    // Join group
  11.  
    socket.on('join group', (uid, gid) => {
  12.  
    for (let i = 0; i < userList.length; i ) {
  13.  
    if (socket.id === userList[i].sid) userList[i].gid = gid;
  14.  
    }
  15.  
    });
  16.  
     
  17.  
    // New group
  18.  
    socket.on('create group', (uid, title) => {
  19.  
    io.emit('fetch group');
  20.  
    });
  21.  
     
  22.  
    // New message
  23.  
    socket.on('message', (uid, gid) => {
  24.  
    for (const user of userList) {
  25.  
    if (gid === user.gid) io.to(user.sid).emit('fetch messages', gid);
  26.  
    }
  27.  
    });
  28.  
     
  29.  
    // Close connection
  30.  
    socket.on('disconnect', () => {
  31.  
    for (let i = 0; i < userList.length; i ) {
  32.  
    if (socket.id === userList[i].sid) userList.splice(i, 1);
  33.  
    }
  34.  
    });
  35.  
    });
  36.  
     
  37.  
    // AppView/index.tsx - Client side
  38.  
     
  39.  
    useEffect(() => {
  40.  
    const socket = socketIOClient(process.env.REACT_APP_SOCKET_URL!, { transports: ['websocket'] });
  41.  
    socket.emit('new user', userData.id);
  42.  
    socket.on('fetch messages', (id: string) => fetchMessages(id));
  43.  
    socket.on('fetch group', fetchGroups);
  44.  
    setSocket(socket);
  45.  
    fetchGroups();
  46.  
    }, []);
学新通

  我发现了express-validator,它在服务器端提供输入验证很有帮助。毫无疑问,我将再次使用。
  
  步骤 03:修复和部署
  
  好的,该应用程序看起来不错,功能运行良好。是时候完成这个投资组合项目并开始一个新的项目了。我不是云解决方案和复杂 CI/CD 方法的专家,所以我会满足于免费的托管服务。云平台有一个适用于后端的免费解决方案。我的节点服务器上传 5 分钟后,它独立运行。我在客户端遇到了一些安全问题。
  
  最后,用户上传的图像通过他们的公共 API存储在我的云帐户中。
  
  即时通讯源码特征:
  
  视频通话
  
  语音通话
  
  实时消息
  
  现场直播
  
  视频会议
  
  SIP 和 VoIP 通话
  
  一键通
  
  屏幕共享
  
  多通道
  
  端到端加密
  
  自定义身份验证
  
  以访客身份登录
  
  随机头像/个人资料图片上传
  
  授权(json web 令牌)
  
  端到端输入验证
  
  创建和加入频道
  
  即时消息
  
  结论
  
  我非常享受在这个项目上的工作并学到了很多东西。很高兴与您分享这个过程,我迫不及待地想听到您的提示和反馈。这个项目无非是一个组合项目,代码开源的,您可以随意使用它。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfiacbc
系列文章
更多 icon
同类精品
更多 icon
继续加载