http://socket.io 是基于 WebSocket 的 C-S 实时通信库,我假设题目问的是 http://socket.io 而非 WebSocket 协议的实现。
http://socket.io 底层是 http://engine.io,这个库实现了跨平台的双向通信。
engine.io 使用了 WebSocket 和 XMLHttprequest(或JSONP) 封装了一套自己的 Socket 协议(暂时叫 EIO Socket),在低版本浏览器里面使用长轮询替代 WebSocket。一个完整的 EIO Socket 包括多个 XHR 和 WebSocket 连接.
我理解的Socket.IO是一个完全由JavaScript实现、基于Node.js、支持WebSocket的协议用于实时通信、跨平台的开源框架, 除了支持WebSocket 还至此多种轮询(Polling)机制来进行通讯。
- WebSocket: 是HTML5的一种新通信协议,它实现了浏览器与服务器之间的双向通讯。
- 多种Polling机制(轮询):
- Adobe Falsh Socket
- AJAX长轮询
- AJAX multipart streaming
- 持久Iframe
- JSON 轮询
原理:
Socket.IO实现了实时、双向、基于事件的通讯机制,它解决了实时的通信问题,并统一了服务端与客户端的编程方式。
启动了Socket以后,就像建立了一条客户端与服务端的管道,两边可以互通有无。它还能够和Express.js提供的传统请求方式很好的结合,即可以在同一个域名,同一个端口提供两种连接方式.
启动了Socket以后,就像建立了一条客户端与服务端的管道,两边可以互通有无。它还能够和Express.js提供的传统请求方式很好的结合,即可以在同一个域名,同一个端口提供两种连接方式.
通俗点的流程就是
socket.io 服务启动时,会先启动一个 ws 服务。 socket.io 会监听 HTTP 服务器的 upgrade 和 request 事件。
当 upgrade 事件触发时,说明可能是 WebSocket 握手,先简单校验下,然后把请求交给 ws 服务进行处理,拿到 WebSocket 对象。
当 request 事件触发时,根据 url 路径判断是不是 socket.io 的 XHR 请求,拿到 res 和 res 对象。
这样就可以正确接收和返回客户端数据了,具体处理过程和前端部分是对应的。
- 服务端启动一个socket服务,并监听'connection'事件。
- 客户端(一般指浏览器)创建一个websocket,并连接服务器端的socket,并绑定接收socket事件的方法。
- 客户连接后,服务端socket就可以向客户端发消息了。
socket通讯可以简单的理解为一个真正意义上的长链接,不主动断开的话该通道一直存在,并且通道的两端可以互相喊话。
普通的请求比如http\xhr这类的,是一个一次性的通讯,当通讯完成后,通道会关闭。
socket一次通讯后并不会关闭通道,这就是他们的区别所在。
当然不同的通讯有不同的协议,我也不是很了解。
官方的demo
服务器端代码:
var
app
=
require
(
'http'
).
createServer
(
handler
)
var
io
=
require
(
'socket.io'
)(
app
);
var
fs
=
require
(
'fs'
);
app
.
listen
(
80
);
// 创建socket,监听连接
io
.
on
(
'connection'
,
function
(
socket
)
{
// 收到连接后,触发 'news' 事件
socket
.
emit
(
'news'
,
{
hello
:
'world'
});
// 接收客户端事件
socket
.
on
(
'my other event'
,
function
(
data
)
{
console
.
log
(
data
);
});
});
服务端:
服务端使用 ws 库实现 WebSocket 协议。socket.io 服务启动时,会先启动一个 ws 服务。 socket.io 会监听 HTTP 服务器的 upgrade 和 request 事件。
当 upgrade 事件触发时,说明可能是 WebSocket 握手,先简单校验下,然后把请求交给 ws 服务进行处理,拿到 WebSocket 对象。
当 request 事件触发时,根据 url 路径判断是不是 socket.io 的 XHR 请求,拿到 res 和 res 对象。
这样就可以正确接收和返回客户端数据了,具体处理过程和前端部分是对应的。
客户端 代码;
var
socket
=
io
(
'http://localhost'
);
// 自定义一个'news'事件
socket
.
on
(
'news'
,
function
(
data
)
{
console
.
log
(
data
);
// 发送事件到服务端
socket
.
emit
(
'my other event'
,
{
my
:
'data'
});
});
这是简单的版本的了,当然他才不是这样简单,我想的是
将socket当作一个类http服务,不同的请求可以当成router+handle的方法来处理,这样就不会有一堆乱七八糟的的on\emit了。