IM通讯系统分析与实战

本文深入探讨了即时通讯(IM)系统的核心要素,包括IP、端口和协议,以及常用协议如TCP/IP、TCP、UDP和HTTP。详细介绍了IM系统中的用户、消息、会话和服务器的角色,强调了实时性、可靠性、一致性和安全性的关键需求。此外,阐述了消息同步、存储和检索的功能,并展示了基于WebSocket的通讯系统示例。最后,通过用户、消息和服务端的代码片段,展示了IM系统的工作流程。
摘要由CSDN通过智能技术生成

前言

什么是IM(即时通讯)?

即时通信(instant message,IM)是指能够即时发送和接收互联网消息等的业务,通常集成了电子邮件、博客、音乐、电视、游戏和搜索等多种功能。
即时通信已经发展成集交流、资讯、娱乐、搜索、电子商务、办公协作和企业客户服务等为一体的综合化信息平台。微软、腾讯、AOL、Yahoo等重要即时通信提供商都提供通过手机接入互联网即时通信的业务,国内最常用的即时通讯软件如QQ、微信、百度hi、网易泡泡、淘宝旺旺等等。用户可以通过手机与其他已经安装了相应客户端软件的手机或电脑收发消息。即时通信不再是一个单纯的聊天工具,它已经发展成集交流、资讯、娱乐、搜索、电子商务、办公协作和企业客户服务等为一体的综合化信息平台。

网络通信的三大要素

  • ip
  • port
  • 协议

常用的网络通讯协议

  • TCP/IP:即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准

  • TCP UDP :TCP和UDP是传输层协议。

  • TCP:面向连接,安全可靠,效率稍低。通过三次握手确保连接的建立。

  • UDP:面向无连接。不可靠。速度快。将数据封包传输,数据包最大64k。

  • Socket:又称“套接字”, 在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

  • HTTP:超文本传输协议, 是一种规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送应用层协议。

IM系统角色分析

用户

系统的使用者,主要有以下特点:

  • 用户信息:如账号,昵称,性别,头像,在线时长等
  • 关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等
  • 用户状态:当前是在线、离线还是挂起等状态

消息

用户之间的传播的内容。其特点如下:

  • 消息类型:消息通常分为文本消息、表情消息、图片消息、视频消息、文件消息等
  • 安全性:是否需要加密以及采用何种加密算法
  • 消息状态:当前消息对方已读还是未读
  • 消息数量:主要是指用户还没读的消息数

会话

指用户之间因聊天而建立起的通讯线路,其特点如下:

  • 会话协议:

    在通信协议的选择上,我们主要有以下几个选择:

    1. 使用 TCP Socket 通信,自己设计协议:58 到家等等
    2. 使用 UDP Socket 通信:QQ 等等
    3. 使用 HTTP 长轮循:微信网页版等等
  • 会话类型:单聊或者群聊,若是群聊还要考虑群组的大小等问题

  • 会话状态:若单向发起的会话,则将消息置为离线状态,否则实时发送

服务器

服务器是会话建立的桥梁,也是消息收发的中转站,其特点如下:

  • 会话管理:保存已建立的会话和销毁已失效的会话
  • 消息传递:将一个用户的消息转发给指定的其它用户
  • 消息队列:实现消息的广播和离线发送
  • 用户管理:用户登陆与验证,用户关系的查询等

客户端

消息的接收端,负责和服务端建立连接,并对消息进行编码和解码。

IM系统功能分析

IM系统的实现目标

1.实时性:保证消息实时触达是互动场景的必备能力。

对于一个实时消息系统,“实时”二字很好地表达了这个系统的基本要求。通过微信和你的好友聊天,结果等半天对方才收到,基本上也没有意愿聊了;直播场景下,如果主播的互动消息房间里的粉丝要等很长时间才能收到,也很难让粉丝们有积极参与的欲望。实时性分为:短轮询,长轮询,WebSocket(长链接)。

2.可靠性:“不丢消息”和“消息不重复”是系统值得信赖的前置条件。

如果说“实时性”是即时消息被广泛应用于各种社交、互动领域的基本前置条件,那么消息的可靠性则是实时消息服务可以“被信赖”的另一个重要特性。这里的可靠性通俗来讲,一般包括两个方面。不丢消息。“丢消息”是互动中让人难以接受的
Bug,某些场景下可能导致业务可用性差,甚至不可用的情况。比如直播间“全员禁言”的信令消息丢失,就可能导致直播室不可控的一些情况。消息不重复。消息重复不仅会对用户造成不必要的骚扰和困惑,可能还会导致比较严重的业务异常,比如直播间“送礼物”的消息由于某种原因被重复发出,处理不妥的话可能会导致用户损失。

3.一致性:“多用户”“多终端”的一致性体验能大幅提升 IM 系统的使用体验

消息的一致性一般来是指:同一条消息,在多人、多终端需要保证展现顺序的一致性。比如,对于单聊场景,一致性是指希望发送方的消息发送顺序和接收方的接收顺序保持一致;而对于一个群的某一条消息,我们希望群里其他人接收到的消息顺序都是一致的;对于同一个用户的多台终端设备,我们希望发送给这个用户的消息在多台设备上也能保持一致性。缺少“一致性”保障的
IM
系统,经常会导致双方沟通过程中出现一些“奇妙的误会”,语言乱序相关的“惨案”。网络上,你可以想象一下发给下属、领导或合作方的几条重要工作内容,如果消息错乱了,后果可能会比较严重。

4.安全性:“数据传输安全”“数据存储安全”“消息内容安全“三大保障方面提供全面隐私保护。

由于即时消息被广泛应用于各种私密社交和小范围圈子社交,因此用户对于系统的隐私保护能力要求也相对较高。从系统使用安全性的角度来看,首先是要求“数据传输安全”,其次是要求“数据存储安全”,最后就是“消息内容安全”。

IM系统核心功能

IM系统中最核心的部分是消息系统,主要分为以下三点:

  • 消息同步:指将消息完整的、快速的从发送方传递到接收方。消息同步系统最重要的衡量指标就是消息传递的实时性、完整性以及能支撑的消息规模。在功能上,至少要支持在线和离线推送,有些IM系统还支持多端同步。
  • 消息存储:指消息的持久化保存。传统消息系统通常只能支持消息在接收端的本地存储,数据基本不具备可靠性。现代消息系统能支持消息在服务端的在线存储,功能上对应的就是消息漫游,消息漫游的好处是可以实现账号在任意端登录查看所有历史消息。
  • 消息检索:消息一般是文本,所以支持全文检索也是必备的能力之一。传统消息系统通常来说也是只能支持消息的本地检索,基于本地存储的消息数据来构建。而现在消息系统在能支持消息的在线存储后,也具备了消息的在线检索能力。

IM系统执行流程

主要分为以下几个步骤:

  1. 用户A输入自己的用户名和密码登录IM服务器,服务器通过读取用户数据库来验证用户身份,如果验证通过,登记用户A的IP地址、IM客户端软件的版本号及使用的TCP/UDP端口号,然后返回用户A登录成功的标志,此时用户A在IM系统中的状态为在线。

  2. 根据用户A存储在IM服务器上的好友列表 ,服务器将用户A在线的相关信息发送给也同时在线的IM好友的PC机,这些信息包括在线状态、IP地址、IM客户端使用的TCP端口(Port)号等,IM好友的客户端收到此信息后将在予以提示。

  3. IM服务器把用户A存储在服务器上的好友列表及相关信息回送到他的客户端机,这些信息包括也在线状态、IP地址、IM客户端使用的TCP端口(Port)号等信息,用户A的IM客户端收到后将显示这些好友列表及其在线状态。

基于websocket的通讯系统

用户对象代码:

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private String mobile;
}

消息对象代码:

@Data
@ToString
public class Message {
    private String id;
    private String msg;
    private String from;
    private String to;
    private String live;
}

服务端代码:

@Component
@ServerEndpoint(value = "/websocket")
@Slf4j
public class Socket {
    public static Map<String, Session> sessionMap = new HashMap<String, Session>();
    @Autowired
    UserService userService;
    private Session session;
    @Resource
    private RedisTemplate redisTemplate;

    @OnOpen
    public void startSocket(Session session) {
        this.session = session;
        log.debug("链接成功");
        if (sessionMap.size() == 0) {
            return;
        }
    }

    @OnMessage
    public void getMessgae(Session session, String str, boolean last) {
        if (session.isOpen()) {
            try {
                log.debug(str);
                Message msg = JsonUtils.jsonToPojo(str, Message.class);
                Message toMessage = msg;
                toMessage.setFrom(msg.getId());
                toMessage.setTo(msg.getTo());

                //开启socket链接时msg的值是newUser
                if (msg.getMsg().equals("newUser")) {
                    //如果存在这个用户
                    if (sessionMap.containsKey(msg.getId())) {
                        //删除掉防止重复(如果更换了电脑或者浏览器。这个操作能保证session与id是唯一对应的且session是最新的)
                        sessionMap.remove(msg.getId());
                    }
                    //将用户id放进去
                    sessionMap.put(msg.getId(), session);
                    //发送在线人数
                    this.pubMessage(session);
                } else {
                    Session toSession = sessionMap.get(msg.getTo());
                    if (toSession != null && toSession.isOpen()) {
                        toSession.getBasicRemote().sendText(JsonUtils.objectToJson(toMessage).toString(), last);
                        //发送在线人数
                        this.pubMessage(toSession);
                    } else {
                        toMessage.setMsg("用户不存在");
                        toMessage.setFrom("系统");
                        session.getBasicRemote().sendText(JsonUtils.objectToJson(toMessage).toString(), last);

                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        } else {
            log.debug("session is closed");
        }
    }


    private void pubMessage(Session session) throws IOException {
        Set userIds = sessionMap.keySet();
        StringBuffer sBuffer = new StringBuffer();
        for (Object str1 : userIds) {
            sBuffer.append(str1.toString() + ",");
        }
        Message message = new Message();
        message.setLive(sBuffer.toString());
        session.getBasicRemote().sendText(JsonUtils.objectToJson(message), true);

        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        operations.set("com.aliencat", 111);
        operations.set("com.aliencat.application", 1, 1, TimeUnit.SECONDS);
    }

}

客户端代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebChat使用示例</title>
    <script src="js/jquery-1.11.3.js" type="text/javascript"></script>
    <script src="js/webchat.js" type="text/javascript"></script>
    <link href="css/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="liveDiv">
    <p>当前在线用户</p>
    <span class="liveSpan">
        </span>
</div>
<div class="container">
    <div class="item">
        <span>称呼:</span>
        <span class="myname_span"></span>
        <span style="margin-left: 50px">联系人:</span>
        <span class="to-user"></span>
    </div>
    <div class="show-message">

    </div>
    <div class="item">
        <p></p>
        <textarea class="msg-context" placeholder="请输入:"></textarea>
    </div>
    <button class="send-btn" onclick="send()">发送</button>
</div>
<script>
    $(function () {
        var item = sessionStorage.getItem("user");
        var parse = JSON.parse(item);
        $('.myname_span').html(parse.username)
        console.log(parse)
        connection(parse.username);
    })
</script>
</body>
</html>
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
【原 书 名】 Communication Systems Fourth Edition 【原出版社】 John Wiley 【作  者】(加)Simon Haykin [同作者作品] [作译者介绍] 【译  者】 宋铁成[同译者作品] 徐平平 徐志勇 等 【丛 书 名】 国外电子与通信教材系列 【出 版 社】 电子工业出版社 【书 号】 7505382543 【出版日期】 2003 年10月 【开 本】 16开 【页 码】 719 【版 次】1-1 【内容简介】本书对通信系统的基础理论和关键环节进行了深入分析,力图让学生在讨论中领会通信的精髓。全书首先给出通信系统的梗概及需要研究的关键技术,接着分章详细讨论了随机过程、连续波调制、脉冲调制、基带脉冲传输、信号空间分析、带通数据传输、扩频调制、多用户无线通信、信息论基础以及差错控制编码等。各章都附有大量习题,便于学生实践掌握。书中还给出了很有价值的附录,包括概率论、信号和系统描述、贝叶斯函数、超几何分布函数汇总、密码学方面的介绍以及一些有用的表格等。全书强调通信理论的统计基础,并给出了用MATLAB模拟的8个计算机实验,这些实验几乎覆盖了各章节的主要内容,形成了独特的通信理论“软件实验室”。 【编辑推荐】随着微电子技术、计算机技术、激光技术、卫星与光纤等相关信息技术的发展,特别是计算机与通信的有机结合,现代通信正经历着一场变革。在这场变革中,各种新技术、新手段、新业务、新系统层出不穷,现代通信的内容也日趋丰富。在通信新技术不断产生,新需求逐步扩展的背景下,建立在多网互连互通、多个系统集成、多种技术综合应用基础上的一体化通信、全球个人通信迅速发展,这就要求通信技术工作者和通信工程等专业的学生不仅深入学习本专业的典型通信系统,还要全面学习和了解目前广泛应用的各种现代通信系统,以全面、系统地了解现代通信的目的。本书正是为了实现这一目的而编写的。 作者介绍:Simon Haykin是国际电子电气工程界的著名学者,加拿大皇家学会院士,IEEE会士,于1953年获得英国伯明翰大学博士学位,现任加拿大麦克马斯特大学教授,在该校创办了通信研究实验室并长期担任主任。他曾经获得IEEE McNaughton奖章,在神经网络、通信、自适应滤波器等领域成果颇丰,著有多种标准教材。 目录 第1章 随机过程 1.1 简介 1.2 随机过程的数字定义 1.3 平稳过程 1.4 均值、相关函数和协方差函数 1.5 遍历过程 1.6 随机过程通过一个线性时不变滤波器 1.7 功率谱密度 1.8 高斯过程 1.9 噪声 1.10 窄带噪声 1.11 基于同相和正交分量的窄带噪声表示法 1.12 基于包络和相位分量的窄带噪声表示法 1.13 正弦信号加窄带噪声 1.14 计算机实验:平衰落信道 1.15 总结与讨论 注释与参考 习题 第2章 连续波调制 第3章 脉冲调制 第4章 基带脉冲传输 第5章 信号空间分析 第6章 通带数据传输 第7章 扩频调制 第8章 多用户无线通信 第9章 信息论基础 第10章 差错控制编码 附录1 概率论 附录2 信号与系统简述 附录3 贝塞尔函数 附录4 汇合型超几何函数 附录5 密码学 附录6 表格 术语表 参考文献 索引
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值