WebSocket 简介

传统的客户端和服务器通信协议是HTTP:客户端发起请求,服务端进行响应,服务端从不主动勾搭客户端。

这种模式有个明显软肋,就是同步状态。而实际应用中有大量需要客户端和服务器实时同步状态的场景,比如聊天室、股票行情、在线共享文档等都需要客户端实时拿到服务器的最新状态。

针对这种实时同步的需求,一种简单的方式是轮询,比如每隔5s发一次http请求去拿服务器最新的状态数据。但这种方式会存在数据延迟,浪费带宽等副作用。

更完美的方式是使用WebSocket,浏览器原生支持,W3C标准协议,客户端和服务器建立持久性连接可以互发消息。

socket.io 简介

socket.io 是一个类库,内部封装了WebSocket,可以在浏览器与服务器之间建立实时通信。

如果某些旧版本的浏览器不支持WebSocket,socket.io会使用轮询代替。另外它还具有可发送二进制消息、多路复用、创建房间等特性,因此相比直接使用原生WebSocket,socket.io是更好的选择。

开发一个实时应用主要分两部分:服务端和客户端,socket.io分别提供了相应的npm包供我们方便地调用。

接下来就通过一个生动形象且有趣的栗子分别介绍这两大块。

现在假设李白,瑶,吕布,后羿,貂蝉5个人加入了一个叫 KPL 的房间,在文章结束时我们将拥有一个麻雀虽小五脏俱全的峡谷英雄在线聊天室

服务端api

首先安装socket.io提供的服务端npm包:

npm i socket.io

可以与 Express 框架配合使用:

const http = require('http')
const app = require('express')()
const server = http.createServer(app)
const io = require('socket.io')(server)
server.listen(3000)

也可以与 Koa 框架配合使用

const http = require('http')
const Koa = require('koa')
const app = new Koa()
const server = http.createServer(app.callback())
const io = require('socket.io')(server)
server.listen(3000)

使用起来就是这么简单。接下来就可以写业务逻辑啦

io.on('connect', client => { // client 即是连接上来的一个客户端
console.log(client.id) // id 是区分客户端的唯一标识 client.on('disconnect', () => {}) // 客户端断开连接时调用(可能是关掉页面,网络不通了等)
})

connectdisconnect 是 socket.io 内置的事件类型,用于在客户端连接和断开的时候做一些事情。

在客户端建立连接时需要把他们加入到一个房间里去,类似创建了一个聊天室

  console.log(client.id)
+ client.join('KPL') // 将客户端加入到 KPL 房间内
client.on('disconnect', () => {})

紧接着瑶进来秒发了首条消息:我打野,不给就送

服务器在收到这条振奋人心的消息后需要立即同步给其他四位队友

  client.join('KPL')
+ client.on('talk', message => {
+ client.to('KPL').emit('talk', message) // 发送给房间里的每个人,除了发送者
+ })
client.on('disconnect', () => {})

服务端的功能到这基本上就开发完了。创建了一个房间,并在收到成员消息时立即同步给房间里的其他成员

客户端api

socket.io 为客户端提供了另一个npm包,直接安装

npm i socket.io-client

接下来就可以在页面上建立到服务器的连接啦

import io from 'socket.io-client'

const socket = io() // 建立连接

向服务器发送消息

  const socket = io()
+ socket.emit('talk', '我打野,不给就送')

接收服务器发来的消息

  const socket = io()
+ socket.on('talk', message => {
+ })

李白看到了瑶的消息,强忍住问候对方家人的冲动,像哄那啥似地说道:

  socket.on('talk', message => {
+ socket.emit('talk', '你买个石头骑在我头上他不香么')
})

客户端的功能到这基本上也开发完了。核心api就是on和emit用于收发消息,既简单又优雅。

最后

至此一个可以实时发送接收消息的聊天室就完成了,虽然简陋,但核心功能完备。

瑶最终倔强地打了野,李白选择了上路,3分钟被对面捶到高地,后羿在家里等鸟,吕布和貂蝉躲在蓝buff旁边的草丛里聊天,就这样在李白和瑶互相拉票举报对方的全局消息中游戏结束

3分钟接入socket.io使用的更多相关文章

  1. Socket.io和Redis写Realtime App 之express初试

    第一步:用npm下载express前端框架 注意事项:首先要确保已经安装了node.js和 npm 然后在项目中创建一个package.json文件,不能完全为空不写,至少要有两个大括号,不然怎么证明 ...

  2. 解决Socket.IO在IE8下触发disconnect时间过长

    本文地址: http://www.cnblogs.com/blackmanba/p/solve-socketIO-IE8-emit-disconnect-too-long.html或者http://f ...

  3. 很幽默的讲解六种Socket IO模型

    很幽默的讲解六种Socket IO模型 本文简单介绍了当前Windows支持的各种Socket I/O模型,如果你发现其中存在什么错误请务必赐教. 一:select模型二:WSAAsyncSelect ...

  4. 很幽默的讲解六种Socket IO模型 Delphi版本(自己Select查看,WM_SOCKET消息通知,WSAEventSelect自动收取,Overlapped I/O 事件通知模型,Overlapped I/O 完成例程模型,IOCP模型机器人)

    很幽默的讲解六种Socket IO模型(转)本文简单介绍了当前Windows支持的各种Socket I/O模型,如果你发现其中存在什么错误请务必赐教. 一:select模型 二:WSAAsyncSel ...

  5. 使用Socket.IO做单页SPA应用更新

    单页应用的挑战之一是确保客户端软件和服务器应用相匹配. 举例:如果一个用Bobbie在他的浏览器中加载我们的单页应用,五分钟之后我们更新了服务器应用.现在Bobbiede遇到了问题,因为我们对服务器做 ...

  6. 在web浏览器上显示室内温度(nodeJs+arduino+socket.io)

    上次的nodejs操作arduino入门篇中实现了如何连接arduino.这次我们来实现通过arduino测量室内温度并在浏览器上显示出来. [所需材料] 硬件:LM35温度传感器,arduino u ...

  7. Node学习笔记(三):基于socket.io web版你画我猜(二)

    上一篇基础实现的功能是客户端canvas作图,导出dataURL从而实现图片信息推送,下面具体讲下服务端的配置及客户端的配置同步 首先先画一个流程图,讲下大概思路 <canvas id=&quo ...

  8. node.js+socket.io配置详解

    由于我是在win7的环境下,在这里就以win7系统为例进行讲解了. 首先需要在nodejs官网下载最新版的node.js,下载完毕直接安装即可,安装成功后在cmd命令行中执行node指令,如下结果就说 ...

  9. 使用Node.js+Socket.IO搭建WebSocket实时应用

    Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...

随机推荐

  1. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  2. P3810 陌上花开 CDQ分治

    陌上花开 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3810 题意: \[ 有n 个元素,第 i 个元素有 a_i. b_i. c_i 三个属性 ...

  3. HBase 原理

    遗留问题: 数据在更新时首先写入Log(WAL log)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的 ...

  4. 如何修改eclipse中Dynamic web module的 version

    我们直接在eclipse中修改Dynamic Web Module的话会报错,改不了的 所以我们可以找到项目文件中的.setting文件下的org.eclipse.wst.common.project ...

  5. Kafka 集群在马蜂窝大数据平台的优化与应用扩展

    马蜂窝技术原创文章,更多干货请订阅公众号:mfwtech Kafka 是当下热门的消息队列中间件,它可以实时地处理海量数据,具备高吞吐.低延时等特性及可靠的消息异步传递机制,可以很好地解决不同系统间数 ...

  6. map类型转为实体类

    BareBaseRequest fromJson = JSON.parseObject(JSON.toJSONString(map), BareBaseRequest.class);

  7. 1059 C语言竞赛 (20 分)C语言

    C 语言竞赛是浙江大学计算机学院主持的一个欢乐的竞赛.既然竞赛主旨是为了好玩,颁奖规则也就制定得很滑稽: 0.冠军将赢得一份"神秘大奖"(比如很巨大的一本学生研究论文集--). 1 ...

  8. 不懂Neo4j?没关系,先学增删改查

    从上篇文章中我们了解到了什么是Neo4j.为什么要用Neo4j.什么场景使用 以及怎么安装,如果您还不想熟悉,点击此处,传送过去哦~ 既然Neo4j是一个图数据库,那么毫无疑问,增删改查是必不可少的, ...

  9. Swift之代码混淆的调研实施小记

    背景: 最近做APP备案,需要对项目做一系列对优化改进,其中就包括了代码混淆,顾名思义,混淆是为了代码安全,是为了增加逆向破解的难度与复杂度. 目前市面上,免费和付费都有,一些公司对APP加固已经做成 ...

  10. oracle mysql sql 根据一张表更新另一张表

    update CDINFO.Dept_Dict tab1 set PART_FLAG = (select PART_FLAG from DICT.DEPARTMENT_DICT@zyhis4 tab2 ...