WebSocket - 从零开始搭建网页聊天室

采用 WebSocket 协议,倾力打造网页端聊天室,亲测兼容 Chrome, Firefox, Sogou 浏览器

image

系统概述

技术结构

webpack

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

在该例中,我们用其编译和合并压缩 ES5 以上 JS、SASS/SCSS、各种图片和字体资源等,并建立开发模式下热重载服务端,以方便系统调试。

jQuery

jQuery 是一个“写的更少,但做的更多”的轻量级 JavaScript 库。

在该例中,我们用其操作 DOM 节点。

WebSocket

WebSocket 是基于TCP的一种新的网络协议,不同于 HTTP 一次请求一次响应的机制,它允许服务器主动发送信息给客户端,由此衍生了许多基于 WebSocket 的 web 即时应用。

在该例中,我们采用 node 第三方 ws 模块以建立网页即时通讯服务端。

核心功能

  • 当打开页面时,系统会为用户随机分配一个名称

  • 用户可以手动修改名称,系统将向所有客户端广播消息以同步数据

  • 当用户 建立/关闭 连接时,系统将广播消息通知所有客户端创建新的联系人项目

  • 用户可以向所有参与者或指定参与者发送消息

原型设计

原型图

image

process on 链接地址

流程设计

流程图

image

process on 链接地址

流程描述

打开页面

image
  1. 打开页面时,客户端为用户分配随机用户名,并向服务端发送 open 消息
    // 消息格式
    {
      type: 'open',
      payload: {
        name
      }
    }
  1. 服务端接收 open 消息,转发至服务端 Mediator

  2. Mediator 根据 contactCounter 生成客户端 id 号,并新增 contact 对象,之后进入回调流程 4、5

  3. 服务端向新建连接的客户端发送 load 消息,之后进入流程 6

    // 消息格式
    {
      type: 'load',
      payload: {
        from: {id, name},
        contactList: mediator.contactList(), // 联系人列表
        talkHistory: mediator.talkHistory().filter(item => item.to.id === 0) // 聊天记录中群发的消息
      }
    }
  1. 服务端向原有客户端发送 contact 消息,之后进入流程 7
 // 消息格式
 {
   type: 'contact',
   payload: {
     id, name
   }
 }
  1. 新建连接的客户端接收 load 消息,转发至 Mediator,初始化联系人列表和聊天历史记录并渲染 UI

  2. 原有客户端接收 contact 消息,转发至 Mediator,新增联系人列表项并渲染 UI

发送消息

image
  1. 用户输入并发送信息,客户端向服务端发送 message 消息
   // 消息格式
   {
     type: 'message',
     payload: {
       from: {id,name},
       to: {id,name},
       msg,
       timestamp
     }
   }
  1. 服务端接收 message 消息,转发至服务端 Mediator

  2. Mediator 根据 talkCounter 生成聊天记录 id 号,并新增聊天记录,之后进入回调流程 4

  3. 服务端向目标客户端发送 message 消息,消息格式同流程 1

  4. 客户端接收 message 消息,转发至客户端 Mediator

  5. 客户端 Mediator 新增聊天记录项并渲染 UI

修改用户名

[图片上传中...(image-8a62d4-1518571606792-1)]

  1. 用户修改用户名时,客户端向服务端发送 nickname 消息
   // 消息格式
   {
       type: 'nickname',
       payload: {
         id: targetId,
         name: modifiedName
       }
   }
  1. 服务端接收 nickname 消息,转发至服务端 Mediator

  2. Mediator 修改目标用户的信息和与之相关的所有聊天历史记录,之后进入回调流程 4

  3. 服务端向所有建立连接的客户端发送 reload 消息

    // 消息格式
    {
      type: 'reload',
      payload: {
        contactList: mediator.contactList(), // 联系人列表
        talkHistory: mediator.talkHistory().filter(record => { // 过滤和当前 client 有关的聊天记录
          return record.from.id === client.id || record.to.id === client.id || record.to.id === 0
        })
      }
    }
  1. 客户端接收 reload 消息,转发至客户端 Mediator

  2. 客户端 Mediator 更新联系人列表和聊天历史记录并渲染 UI

关闭页面

image
  1. 关闭页面时,服务端捕获 close 事件并向所有客户端发送 lose 消息
    // 消息格式
    {
      type: 'lose',
      payload: {
        id
      }
    }
  1. 客户端接收 lose 消息,转发至客户端 Mediator

  2. Mediator 移除联系人列表项并渲染 UI

补充说明

  • 系统只建立一个共享聊天室,其中 WebSocket Server 服务于所有 Client 端。

  • 系统不以任何方式留存用户信息,打开页面即视为新的客户端建立连接,关闭页面即视为客户端永久断开连接。

  • 兼容 Chrome, Firefox, Sogou 浏览器,不兼容 IE

源码下载

GitHub

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,659评论 0 15
  • 你们没有一个人会明白,无论是从前还是现在,你们都不明白。如果,你们让我作出选择,我一定毫不犹豫地选择你,没有抱歉的...
    沐柒染阅读 268评论 1 1
  • 01、 我一向以为自己是个泪点很高的人,从前听信了某种言论,说戴隐形眼镜的人不能哭,一哭就会瞎掉,所以我出门看电影...
    烙子阅读 881评论 1 2
  • 教程一:Python爬虫学习系列教程 这个博主的这个爬虫学习系列教程,很详细啊,从入门到实战、进阶等都有详细的文档...
    菜鸟窝阅读 14,327评论 0 28