前言:
  大家刚学socket编程的时候, 往往以聊天室作为学习DEMO, 实现简单且上手容易. 该Demo被不同语言实现和演绎, 网上相关资料亦不胜枚举. 以至于很多技术书籍在讲解网络相关的编程时, 不再采用聊天室做为基础案列, 而采用其他案例. 比如之前火热一时的"你猜我画", 以避免显得很大众.
  但说实话, 几乎所有的网络程序追踪溯源, 都可以从聊天室中找到影子. 在线聊天室也不局限于简单的单机服务, 其分布式实现技术含量十足. 犹如达芬奇画鸡蛋, 中间虽枯燥, 但坚持不懈, 精益求精. 终于水滴石穿, 从量变到质变.
  本章将讲讲, websocket的协议和javascript版的API.

websocket协议:
  websocket基于tcp的双向通讯协议. 其协议可以分为两个部分, 握手数据传输. 其握手协议构建于http/https, 而数据传输协议则脱离于http/https.
  websocket协议历经了很多版本的修改和升级, 字段和约定的差异, 使得编码时需要注意版本的兼容性. 当前使用最普遍的是版本13.
  其协议uri可以表示为"ws://{host}:{port}/{path}", 在ssl/tls下是"wss://{host}:{port}/{path}".
  • 握手协议
  在该阶段, 其交换为request/response的方式进行.

  
  如简单的例子为案例, 其http请求头中包含如下的字段:
  
  Connection: Upgrade
  Upgrade: websocket
  Sec-WebSocket-Key: A2mIDkRXEgl0+79uPwhsOw==
  Sec-WebSocket-Version: 13
  服务端通过识别header中的Upgrade:websocket字段来区分正常的http请求还是websocket协议.
  而Sec-WebSocket-Key则是客户端生成的一个随机key, 用于和服务端进行的验证工作.
  服务端的响应如下所示:
  
  Sec-WebSocket-Accept: hQCy41pGdjZ222NKXfyrxQUHZEQ=
  其http响应码为101, Sec-WebSocket-Accept为服务端对应于客户端Sec-WebSocket-Key的验证值.
  其具体的算法, 可以描述如下:

${Sec-WebSocket-Accept}=base64(sha1(${Sec-WebSocket-Key}+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))

  • 数据协议
  在该阶段, 客户端和服务器其数据交换格式, 就约定为Frame模式了. 一般一条消息为一个frame, 当然一个消息可以由多个frame组成. 这样的好处, 就像http的chunk模式一样, 一边生成一边传输.
  Frame具体的定义如下所示:
  
  每个字段都有其具体的含义, 这边就不再具体的展开了.
  其Frame的分类可以大致如下:
  
  Ping/Pong Frame由应用层协议本身完成, 这样基于websocket开发的网络应用服务, 就可以少去了死链检测/重连这一环节了.
  Text Frame往往用的比较多, 也有使用Binary Frame的, 比如基于websocket实现的MQTT服务.
  Connection Close Frame是一种友好协商断掉连接的一种方式.

Javascript版API:
  WebSocket其对应的javascript代码如下:

// *) websocket链接本身的状态
WebSocket.CONNECTING = 0;
WebSocket.OPEN = 1;
WebSocket.CLOSING = 2;
WebSocket.CLOSED = 3; // *) websocket实体对象的成员
WebSocket.prototype.url = null;
WebSocket.prototype.readyState = 0;
WebSocket.prototype.bufferedAmount = 0;
WebSocket.prototype.extensions = null;
WebSocket.prototype.protocol = null; // *) websocket实体对应的回调函数, 需要被继承实现
WebSocket.prototype.onopen = 0;
WebSocket.prototype.onmessage = 0;
WebSocket.prototype.onerror = 0;
WebSocket.prototype.onclose = 0; // *) websocket实体的send/close方法
function WebSocket(url,protocols) {}
WebSocket.prototype.send = function(data) {};
WebSocket.prototype.close = function(code,reason) {};

  主要还是websocket对应的回调函数实现, 当然也需知道websocket本身所处的状态.

总结:
  该篇博文有堆砌之感, 但如果你想实现一个基于websocket实现的聊天室, 对其内部的协议和流程需要有个清晰的了解. 特别是之后的基于Netty开发的服务器, 虽然可以照猫画虎, 但知其然不知其所以然.
  本文参考了websocket的wiki, 以及rfc说明.

写在最后:
  
如果你觉得这篇文章对你有帮助, 请小小打赏下. 其实我想试试, 看看写博客能否给自己带来一点小小的收益. 无论多少, 都是对楼主一种由衷的肯定.

  

在线聊天室的实现(1)--websocket协议和javascript版的api的更多相关文章

  1. 在线聊天室的实现(2)--基于Netty 4.x的Echo服务器实现

    前言: 就如前文所讲述的, 聊天室往往是最基本的网络编程的学习案例. 本文以WebSocket为底层协议, 实现一个简单的基于web客户端的Echo服务. 服务器采用Netty 4.x来实现, 源于其 ...

  2. 使用WebSocket实现简单的在线聊天室

    前言:我自已在网上找好了好多 WebSocket 制作 在线聊天室的案列,发现大佬们写得太高深了 我这种新手看不懂,所以就自已尝试写了一个在线简易聊天室 (我只用了js 可以用jq ) 话不多说,直接 ...

  3. 基于Server-Sent Event的简单在线聊天室

    Web即时通信 所谓Web即时通信,就是说我们可以通过一种机制在网页上立即通知用户一件事情的发生,是不需要用户刷新网页的.Web即时通信的用途有很多,比如实时聊天,即时推送等.如当我们在登陆浏览知乎时 ...

  4. 百度前端面试题-类似slack的在线聊天室

    别人国庆出去玩,我在家写代码的感觉也是很不错哒. 首先介绍一下技术架构吧! 使用了js框架:FFF,zepto,jquery,md5.min.js 前端框架:Bootstrap 后端:野狗,部分PHP ...

  5. swoole中websoket创建在线聊天室(php)

    swoole中websoket创建在线聊天室(php) swoole现仅支持Linix,macos 创建websocket服务器 首先现在服务器创建一个websocket服务器 <?php // ...

  6. Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)

    简单介绍 关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室) 在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现 ...

  7. 三、jQuery--jQuery基础--jQuery基础课程--第12章 jQuery在线聊天室

    在线聊天室案例 一.功能简介: 1.用户需要登录后才能进入聊天室交流 2.已无刷新的方式,动态展示交流后的内容和在线人员的基本信息 3.登录后的用户可以提交文字和表情图标 技术重点:利用ajax的无刷 ...

  8. 基于JQuery+JSP的无数据库无刷新多人在线聊天室

    JQuery是一款非常强大的javascript插件,本文就针对Ajax前台和JSP后台来实现一个无刷新的多人在线聊天室,该实现的数据全部存储在服务端内存里,没有用到数据库,本文会提供所有源程序,需要 ...

  9. 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

    基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...

随机推荐

  1. jquery之replaceAll(),replaceWith()方法详解

    一:replaceAll() replaceAll()函数用于使用当前匹配元素替换掉所有的目标元素. 该函数属于jQuery对象(实例). 语法 jQuery 1.2 新增该函数. jQueryObj ...

  2. 一键式Spring集成工具 Spring Boot

    最近公司使用Spring boot进行开发,稍微了解一下,不过自我感觉把集中式配置applicate.properties搞明白,注解用过Spring MVC的boot绝对没问题的 比如拦截器:@As ...

  3. JAVA的UDP协议交互信息

    由于要做app的UDP协议交互,所以就特地学习了下,其实也就类似于java的server和socket,下面就写了个简单的demo 服务端: package com.test1; import jav ...

  4. HQL 参数绑定、唯一结果、分页、投影总结(上)

    我们先总结一下HQL语句常用语法: from子句:; select子句:用于选取对象和属性; where子句:用于表达查询语句的限制条件; 使用表达式:一般用在where子句中; order by子句 ...

  5. java高薪之路__008_Annotation

    元注解 共有4种 @Retention 表示需要在什么级别保存该注释信息(生命周期) |--- RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉 |--- Reten ...

  6. 机器学习职位 & 面经

    http://www.cnblogs.com/peileyuan/p/4775453.html <浅谈机器学习的职业发展方向> http://blog.sina.com.cn/s/blog ...

  7. transition&transform,CSS中过度和变形的设置

    设置样式的过度效果transition-property: none/all; transition-duration:2s;运动时间,默认是0秒 transition-delay:0s; 延迟时间默 ...

  8. Mybatis 开启事务@Transactional

  9. uploadify 火狐不兼容问题解决方案

    uploadify可能在某些浏览器不工作,uploadify兼容方法: 在swf后面加个参数就可以了 uploadify/uploadify.swf?var='+(new Date()).getTim ...

  10. Java:Collection List Set

    Java:集合 常见集合:List Set List 特点:元素是有序的,而且元素可以重复,因为该集合体系有索引. 常见的三个子类:ArrayList.LinkedList.Verctor List集 ...